Ouaf SDK 4202 E39199
Ouaf SDK 4202 E39199
Ouaf SDK 4202 E39199
July 2013
Oracle Utilities Application Framework Software Development Kit Developer's Guide
Release 4.2.0.2.0
E39199-02
July 2013
Copyright 2013, Oracle and/or its affiliates. All rights reserved.
This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected
by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce,
translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse
engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited.
If this software or related documentation is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, the
following notice is applicable:
U.S. GOVERNMENT RIGHTS
Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer
software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.
As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the
applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR
52.227-19, Commercial Computer Software License (December 2007). Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.
This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended
for use in any inherently dangerous applications, including applications which may create a risk of personal injury. If you use this software or
hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy and other measures to
ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in
dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
This software or hardware and documentation may provide access to or information on content, products and services from third parties. Oracle
Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third party content, products
and services. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of
third party content, products or services.
2
Contents
Oracle Utilities Software Development Kit..................................................................... 13
User Guide...........................................................................................................................14
Overview................................................................................................................................................ 14
Development Environment.................................................................................................................... 14
Overview.................................................................................................................................... 15
The App Server is the Development Environment....................................................... 15
Development App Server is Local, Not Shared............................................................15
Repository for Project....................................................................................................15
Components of the Software Development Kit........................................................................ 15
Project Development Database......................................................................................17
Project Repository..........................................................................................................17
Development Workstation............................................................................................. 17
Directory Structure.................................................................................................................... 17
The App Server Directory............................................................................................. 17
Standard App Server Directory Structure......................................................... 17
Additional Directories for Development........................................................... 19
Pertinent Directories in the App Server............................................................ 20
Client Directory................................................................................................. 20
Synchronizing with the Project Repository...............................................................................21
Versions......................................................................................................................................22
Version Number.............................................................................................................22
Compatibility with Products..........................................................................................22
Updates...........................................................................................................................22
Moving up to a New Update.........................................................................................23
Stabilize the Project...........................................................................................23
Install the Update...............................................................................................23
Moving up to a New Version of a Product...................................................................23
Stabilize the Project on the Old Version of the Product................................... 23
Prepare the Database for the New Project........................................................ 24
Set up the Repository for the New Project....................................................... 24
Set up Development Workstations.................................................................... 24
Product Single Fixes..................................................................................................................24
Build Server........................................................................................................................................... 24
What is a Build Server?............................................................................................................ 25
The 'Build Master'..................................................................................................................... 25
Version Control System Requirements..................................................................................... 26
Oracle Utilities Software Development Kit.............................................................................. 26
Version Control System Setup.................................................................................................. 26
Client Spec Setup.......................................................................................................... 26
Application Server Refresh....................................................................................................... 26
Application Server Refresh Scripts............................................................................... 26
setupEnv2xx.cmd............................................................................................... 27
setAppserverEnv.bat.......................................................................................... 27
AppServerRefresh.bat........................................................................................ 27
build.xml............................................................................................................ 28
Application Server Refresh Procedure.......................................................................... 30
JUnit testing........................................................................................................................................... 30
Standard test cases.....................................................................................................................31
Testing Searches............................................................................................................ 31
3
Testing Maintenance Classes.........................................................................................32
Testing Add on Maintenance Class...................................................................33
Testing Change on Maintenance Class............................................................. 34
Testing Delete on Maintenance Class............................................................... 34
Test default actions on Maintenance Class....................................................... 34
Testing Entity Page Maintenance Classes.....................................................................35
Testing Add on Entity Page Maintenance Class............................................... 35
Testing Change on Entity Page Maintenance Class..........................................35
The Comparisons............................................................................................... 36
Test default actions on Entity Page Maintenance Class....................................36
Testing Business Entity Validation............................................................................... 37
Test handleChange / handleAdd / etc code...................................................................40
Testing for Warnings.....................................................................................................41
Maintenance Classes..........................................................................................41
Entity tests..........................................................................................................42
Technical Background........................................................................................................................... 42
Technology Overview................................................................................................................43
Key Advantages............................................................................................................. 44
Portability........................................................................................................... 44
Distribution.........................................................................................................44
OUAF Web Services................................................................................................................. 44
SPL Service XML Metainfo Files............................................................................................ 44
Example using Page Service......................................................................................... 45
Example Using Search Service..................................................................................... 47
Server Architecture Overview................................................................................................... 48
Client Architecture Overview....................................................................................................48
Introduction.................................................................................................................... 48
Client Architecture Discussion...................................................................................... 48
SPL Client API.......................................................................................................................... 51
Overview........................................................................................................................ 51
Client API Discussion................................................................................................... 51
JavaScript Invocation Context...........................................................................51
Data Representation and Localization...............................................................51
Core JavaScript Classes.....................................................................................52
Free Functions....................................................................................................56
Meta-data Overview.............................................................................................................................. 61
Generated Tab Menu Meta-data................................................................................................61
Generated UI Program Component Meta-data..........................................................................62
Menu and Navigation Meta-data...............................................................................................63
Table-Related Meta-data............................................................................................................64
Maintenance Object Meta-data..................................................................................................65
Defining Generator Tools Meta-data........................................................................................ 66
Setting up Fields............................................................................................................ 66
Fields - Main..................................................................................................... 66
Fields - Tables Using Field............................................................................... 67
Setting up Foreign Key References.............................................................................. 68
FK References....................................................................................................68
Setting up Lookup Tables............................................................................................. 70
Lookup Tables................................................................................................... 70
Setting up Navigation Options...................................................................................... 71
Navigation Option - Main................................................................................. 72
Setting up Services........................................................................................................ 74
Services.............................................................................................................. 74
Setting up Tables........................................................................................................... 75
4
Tables - Main.....................................................................................................76
Tables - Fields................................................................................................... 78
Tables - Constraints...........................................................................................79
Tables - Referred by Constraints...................................................................... 80
Setting up Menus...........................................................................................................81
Menus - Main.................................................................................................... 81
Menus - Menu Lines......................................................................................... 82
Setting up Maintenance Objects....................................................................................84
Maintenance Objects - Main............................................................................. 84
Maintenance Objects - Options......................................................................... 86
Maintenance Objects - Algorithms....................................................................86
Maintenance Object - Maintenance Object Tree...............................................88
Development Process.............................................................................................................................88
Hooking into User Exits............................................................................................................89
Hooking into UI Javascript User Exits......................................................................... 89
Hooking into Java User Exits (interceptors)................................................................. 89
Extending Business Entities...................................................................................................... 89
Extending the Business Interface.................................................................................. 90
Extending the Specialization Interface..........................................................................90
Creating New Business Entities.................................................................................... 90
Specifying the Business Interface................................................................................. 90
Specifying the Specialization Interface......................................................................... 91
Extending Maintenance Classes................................................................................................ 91
Maintenance extensions................................................................................................. 91
Creating Business Components................................................................................................. 92
Plugging in Algorithms............................................................................................................. 92
Creating Portals and Zones....................................................................................................... 93
Creating Background Processes................................................................................................ 93
Testing Background Processes...................................................................................... 94
Creating MOs and Maintenance Transactions.......................................................................... 94
Building the Application Viewer.............................................................................................. 95
Creating Javadocs for CM Source Code.......................................................................95
Generate CM Javadocs...................................................................................... 96
Recreate the Javadoc Indices.............................................................................96
Cookbook............................................................................................................................................... 96
Hooking into User Exits............................................................................................................96
Hooking into Maintenance Class User Exits................................................................ 96
Maintenance extensions..................................................................................... 96
Hooking into UI Javascript User Exits......................................................................... 98
Miscellaneous How-To's....................................................................................99
Hooking into Java User Exits (interceptors)............................................................... 105
Example............................................................................................................105
Maintaining General-Purpose Maintenance Classes............................................................... 106
Maintaining MOs..................................................................................................................... 107
Maintaining Maintenance Classes for MOs................................................................ 107
List Maintenance Classes................................................................................ 108
Maintenance List Filters.................................................................................. 109
List Maintenance Get More.............................................................................109
Maintaining Maintenance Objects...............................................................................110
Maintaining Database Meta-data.............................................................................................110
Maintaining Fields....................................................................................................... 110
Maintaining Tables...................................................................................................... 110
Maintaining Java Classes........................................................................................................ 110
Maintaining Business Entities..................................................................................... 110
5
Business Entity Background............................................................................111
Persistent Classes............................................................................................. 112
Creating the Implementation Class................................................................. 113
Developing Change Handlers.......................................................................... 114
Maintaining Business Components............................................................................. 122
Creating Business Components....................................................................... 122
Component Replacement................................................................................. 123
Calling Components.........................................................................................123
Maintaining Maintenance Classes, including collections............................................123
Maintaining Services............................................................................................................... 123
Maintaining Foreign Key References......................................................................................124
Maintaining Lookup Tables.....................................................................................................124
Maintaining Navigation Keys..................................................................................................124
Maintaining Navigation Options............................................................................................. 124
Maintaining User Interfaces.................................................................................................... 124
Maintaining Menus.................................................................................................................. 125
Maintaining Application Security........................................................................................... 125
Maintaining UI Components (Translation)............................................................................. 125
Flushing Server and Client Caches............................................................................. 125
User Language............................................................................................................. 126
Modifying Dialog Titles.............................................................................................. 126
Modifying Transaction Titles and Tab Labels............................................................ 129
Modifying Field Labels on Pages............................................................................... 132
Modifying Button Labels.............................................................................................136
Modifying Messages....................................................................................................139
Plugging in Algorithms........................................................................................................... 141
Creating Algorithm Spot Implementation Class......................................................... 141
Review Algorithm Spot Definition................................................................. 141
Create Algorithm Component Implementation............................................... 141
Add Algorithm Type................................................................................................... 141
Add Algorithm............................................................................................................. 142
Create References to New Algorithm......................................................................... 143
Maintaining Portals and Zones................................................................................................143
Implementing Custom Zones.......................................................................................144
Key Dependence.......................................................................................................... 144
Creating a New Zone.................................................................................................. 144
Zone Types...................................................................................................... 144
Zone Metadata................................................................................................. 147
Debugging.................................................................................................................... 147
Simple Example: LinkValueGrid................................................................................ 148
XSLT File (/WEB-INF/xsl/linkValueGrid.xsl)............................................... 148
XML Meta Info............................................................................................... 149
Another Example: accountFinancialHistory................................................................150
XSLT File (/WEB-INF/xsl/accountFinancialHistory.xsl)............................... 150
XML Metainfo................................................................................................. 152
The Service Data Buffer..............................................................................................153
XSLT Debugging.........................................................................................................154
HTML Standards......................................................................................................... 154
Maintaining Background Processes.........................................................................................154
Maintaining Background Processes Overview............................................................154
Creating a BatchJob.....................................................................................................155
The BatchJob Annotation................................................................................ 155
Creating JobWork............................................................................................ 156
Declaring a ThreadWorker Class.................................................................... 156
6
Creating a ThreadWorker............................................................................................ 156
Initializing ThreadWork...................................................................................156
Executing a WorkUnit..................................................................................... 156
Finalizing ThreadWork....................................................................................157
Choosing a ThreadExecutionStrategy............................................................. 157
Building the Application Viewer............................................................................................ 157
Creating Table XMLs..................................................................................................157
Creating MO XMLs.................................................................................................... 157
Creating Algorithm XMLs.......................................................................................... 157
Extending Service XMLs............................................................................................ 157
Creating Javadocs for CM Source Code..................................................................... 158
Upgrade JSP to XSLT.............................................................................................................158
Create User Exit Files................................................................................................. 158
Tree User Exit Changes.............................................................................................. 158
Change Template Code in Program Components....................................................... 159
Create XML File with UI Meta-data.......................................................................... 160
Delete the JSP Files.....................................................................................................160
Log into the Application and Test.............................................................................. 160
Utilities................................................................................................................................................. 160
Environment Batch Programs..................................................................................................160
displayEnvironment.bat................................................................................................160
switchEnvironments.bat............................................................................................... 161
createNewEnv.bat........................................................................................................ 161
Services.................................................................................................................................... 161
Batch Program setupSvcXMLPrompted.bat................................................................161
Batch Program updateXMLMetaInfo.bat.................................................................... 161
Eclipse Tools/Wizards............................................................................................................. 162
Batch Program startEclipse.cmd..................................................................................162
Annotation Editor........................................................................................................ 162
Project database information....................................................................................... 167
Maintenance Object wizard......................................................................................... 168
Upgrade JSP to XSLT.............................................................................................................173
Batch Program convertTreePageExits.pl.....................................................................173
convertTreePageExits Purpose........................................................................ 174
convertTreePageExits Description...................................................................174
convertTreePageExits Usage........................................................................... 174
Batch Program convertSubPanelExits.pl.....................................................................174
convertSubPanelExits Purpose........................................................................ 174
convertSubPanelExits Description...................................................................174
convertSubPanelExits Usage........................................................................... 174
SQL Script changeTemplateCodesTTRAndPN.pl...................................................... 174
changeTemplateCodesTTRAndPN Purpose....................................................174
changeTemplateCodesTTRAndPN Description.............................................. 175
Javadocs................................................................................................................................... 175
Batch Program generateJavadoc.bat............................................................................175
Batch Program reindexJavadoc.bat............................................................................. 175
Developer Guide............................................................................................................... 176
Overview.............................................................................................................................................. 176
Java Annotations..................................................................................................................................177
Public API............................................................................................................................................178
SQL Return Codes...................................................................................................................178
Standard Business Methods.....................................................................................................179
Business Entity Public Methods..............................................................................................179
Public Methods............................................................................................................ 179
7
Protected Methods....................................................................................................... 180
Data Transfer Object Methods.................................................................................... 180
Id Methods................................................................................................................... 180
Maintenance Class Public Methods........................................................................................ 181
UI Javascript User Exits..........................................................................................................181
Client User Exit Flow..................................................................................................182
Read Page........................................................................................................ 182
Delete Page...................................................................................................... 183
Save Page.........................................................................................................184
Refresh Page.................................................................................................... 185
Prepare Model for Add....................................................................................186
Update Field.....................................................................................................186
External User Exit Templates..................................................................................... 187
Template Structure...........................................................................................188
Design Approach............................................................................................. 188
Using the External User Exit Templates.........................................................189
Create an External User Exit.......................................................................................189
Find the Name of the JSP File........................................................................189
Determine the Base User Exit.........................................................................192
Uncomment the Function and Add Code........................................................193
Test Your Code................................................................................................193
Field-level Security Client-Side User Exit Example...................................................194
How-To........................................................................................................................ 195
How Do I Control the Initial Focus Within Tab Pages/Grids/Search Pages?...195
How Do I Mark Fields that Won't Make the Model Dirty?............................ 196
How Do I Control the Triggering of Defaults After a Search?....................... 196
How Do I Avoid Automatically Setting Fields to Uppercase?....................... 196
How Can I Force the Save Button to be Enabled?......................................... 197
How Can I Override the Processing After a Change/Add?.............................197
How Do I Prevent the System from Setting Focus to a Widget After an Error? .198
How Do I Prevent Attributes from Being Copied into New List Elements? ....198
How Do I Customize New List Elements?..................................................... 198
How Can I Get My Sequence Numbers to Default Properly on My List Grid? . 198
How Do I Override the Tab Page Shown After an Error in a List (Grid/Scroll)?199
How Do I Disregard Unwanted Criteria from a Search Triggered by a Search Button? 199
How Do I Disregard Unwanted Search Result Columns?...............................200
How Do I Format a Value Based on a Given Format?................................... 200
Java User Exits (interceptors) Interfaces and Classes.............................................................200
IAddInterceptor Interface.............................................................................................201
PageBody aboutToAdd(RequestContext, PageBody)..................................... 201
void afterAdd(RequestContext, PageBody).................................................... 201
IChangeInterceptor Interface....................................................................................... 201
PageBody aboutToChange(RequestContext, PageBody)................................ 202
void afterChange(RequestContext, PageBody)............................................... 202
IDeleteInterceptor Interface......................................................................................... 202
boolean aboutToDelete(RequestContext, PageBody)......................................202
void afterDelete(RequestContext, PageBody)................................................. 203
IReadInterceptor Interface........................................................................................... 203
PageBody aboutToRead(RequestContext, PageHeader)................................. 203
void afterRead(RequestContext, PageBody)................................................... 204
InterceptorError class...................................................................................................204
void setMessageNumber(BigInteger messageNumber)...................................204
void setMessageCategory(BigInteger messageCategory)............................... 204
void setMessageParameters(List messageParameters).................................... 204
8
void setMessageParameterTypeFlags(List messageParameterTypeFlags)......205
InterceptorWarning class............................................................................................. 205
InterceptorWarning(ServerMessage warningMessage)................................... 205
InterceptorWarning(List warningMessages)....................................................205
void addWarningMessage(ServerMessage message)...................................... 205
RequestContext Methods......................................................................................................... 205
String getLanguageCode()........................................................................................... 205
String getUserId()........................................................................................................ 205
Data Objects.............................................................................................................................206
PageHeader and PageBody Methods.......................................................................... 206
Object get(String fieldName).......................................................................... 206
String getString(String fieldName)..................................................................206
boolean getBoolean(String fieldName)........................................................... 206
BigInteger getBigInteger(String fieldName)................................................... 206
void put(String fieldName, Object value)....................................................... 206
PageHeader...................................................................................................................207
PageBody..................................................................................................................... 207
ItemList getList(String name)......................................................................... 207
ItemList........................................................................................................................ 207
ListHeader getHeader()....................................................................................207
String getName()..............................................................................................207
List getList().................................................................................................... 207
void setList(List list)........................................................................................207
ListHeader.................................................................................................................... 207
ListBody....................................................................................................................... 208
String getActionFlag()..................................................................................... 208
CMServiceConfig.xml structure.................................................................................. 208
Application Logs..................................................................................................................................208
Logging within Business Logic...............................................................................................208
Configuring Logging at Runtime............................................................................................ 209
Property Configuration................................................................................................ 209
Trace Flags...................................................................................................................210
Java Programming Standards.............................................................................................................. 210
Rationale...................................................................................................................................210
Guidelines.................................................................................................................................210
Naming Standards....................................................................................................................211
General guidelines....................................................................................................... 211
Entity Naming Guidelines........................................................................................... 212
Collection Naming Guidelines.................................................................................... 212
Class Name...................................................................................................... 212
Collection Name.............................................................................................. 212
Lookup Naming Guidelines.........................................................................................213
Java/COBOL Naming Guidelines............................................................................... 213
Special Cases............................................................................................................... 213
'Type'EntityControllingCharacteristicsfor'Instance'Entities-CharacteristicControls 213
HQL Programming Standards............................................................................................................. 214
Examples.................................................................................................................................. 215
Union queries........................................................................................................................... 215
Performance............................................................................................................................. 216
Raw SQL..................................................................................................................................216
SQL Programming Standards..............................................................................................................216
Composing SQL Statements....................................................................................................216
Prerequisite...................................................................................................................217
Composing a SELECT Statement............................................................................... 217
9
General SELECT Statement Considerations................................................... 217
Selection List................................................................................................... 217
Database-specific Features...............................................................................217
FROM Clause.................................................................................................. 218
WHERE Clause............................................................................................... 218
Sort Order........................................................................................................ 220
Grouping...........................................................................................................220
Existence Checks......................................................................................................... 220
SQL statements to avoid............................................................................................. 221
Decimal Delimiter............................................................................................221
Whenever Statement........................................................................................ 222
Testing SQL Statements.......................................................................................................... 222
Result Data...................................................................................................................222
Performance Testing - Oracle Only............................................................................ 222
Overview.......................................................................................................... 222
What is an Explain Plan?................................................................................ 222
Generate the SQL's Explain Plan.................................................................... 223
Analyze Explain Plan...................................................................................... 225
More Extensive Performance Testing..................................................................................... 226
SQL Development and Tuning Best Practices........................................................................226
Database Design.................................................................................................................................. 228
Database Object Standard........................................................................................................228
Naming Standards........................................................................................................228
Table.................................................................................................................229
Columns........................................................................................................... 229
Indexes............................................................................................................. 229
Sequence...........................................................................................................230
Trigger.............................................................................................................. 230
Column Data Type and Constraints............................................................................ 230
User Define Code............................................................................................ 230
System Assigned Identifier..............................................................................230
Date/Time/Timestamp......................................................................................231
Number.............................................................................................................231
Fixed Length/Variable Length Character Columns.........................................231
Null Constraints............................................................................................... 231
Default Value Setting...................................................................................... 231
Foreign Key Constraints..................................................................................231
Standard Columns........................................................................................................231
Owner Flag...................................................................................................... 232
Version............................................................................................................. 232
System Table Guide............................................................................................................................ 232
What are system tables?.......................................................................................................... 232
Why the standard must be observed?..................................................................................... 232
Guidelines for System Table Updates.....................................................................................233
Business Configuration Tables.................................................................................... 233
Application Security and User Profile............................................................ 233
Currency Code................................................................................................. 233
DB Process.......................................................................................................233
Display Profile................................................................................................. 233
Installation Options..........................................................................................234
Language Code................................................................................................ 234
To do priority and Role...................................................................................234
Development and Implementation System Tables...................................................... 234
Standards.......................................................................................................... 234
10
Algorithm Type................................................................................................235
Algorithm......................................................................................................... 235
Application Security........................................................................................ 235
Batch Control................................................................................................... 235
Business Object................................................................................................236
Business Service.............................................................................................. 236
Characteristics.................................................................................................. 236
Data Area......................................................................................................... 236
Display Icon..................................................................................................... 237
Foreign Key Reference....................................................................................237
Lookup............................................................................................................. 237
Map...................................................................................................................237
Messages.......................................................................................................... 238
Meta data - Table and Field............................................................................ 238
Meta data - Constraints................................................................................... 239
Meta data - Menu............................................................................................ 239
Meta data - Program, Location and Services.................................................. 239
Meta data - Maintenance Object..................................................................... 240
Meta data - Work Tables.................................................................................240
Meta data - Search Object...............................................................................240
Navigation Option............................................................................................240
Portal and Zone................................................................................................240
Sequence...........................................................................................................241
Schema............................................................................................................. 241
Script................................................................................................................ 241
To do Type...................................................................................................... 241
XAI configuration............................................................................................242
XAI Services....................................................................................................242
Oracle Utilities Application Framework only Tables................................................. 242
System Table List.................................................................................................................... 243
Key Generation.................................................................................................................................... 247
Metadata for Key Generation..................................................................................................247
Extending the Application Viewer...................................................................................................... 248
Building Source Code Viewer Extension Information........................................................... 248
Development Performance Guidelines................................................................................................ 249
Object-Relational Mapping: Background................................................................................249
The ORM defers database calls for performance........................................................250
ID Objects.................................................................................................................... 250
Counting a collection...................................................................................................251
Avoid unnecessary work............................................................................................. 251
ORM 'Navigation' is your friend.................................................................................251
How to Pre-load Entities Using Fetch........................................................................ 251
Session Cache.............................................................................................................. 252
Level 2 Cache Applicable for Batch...........................................................................252
Flushing - COBOL and Save Points........................................................................... 252
Avoid Extra SQL.....................................................................................................................252
Prepared statement - use binding............................................................................................ 253
Service Script vs. Java Services..............................................................................................253
Java-To-COBOL Interaction Overhead...................................................................................253
Java Performance Patterns.......................................................................................................254
Batch Performance...................................................................................................................254
Commit Considerations............................................................................................... 254
Clustered vs. Distributed Mode Performance: Clustered is Preferred.........................254
Light Business Objects............................................................................................................ 254
11
Data Explorer........................................................................................................................... 256
Zone Configuration......................................................................................................256
Table Indices and SQL................................................................................................256
UI Maps and BPAs................................................................................................................. 257
Diagnosing Performance Issues...............................................................................................258
Fiddler.......................................................................................................................... 258
OUAF 'Show Trace' button......................................................................................... 258
Log Service times in spl_service.log.......................................................................... 258
Optimization and Performance Profiling................................................................................ 258
Basic Logging.............................................................................................................. 258
Timing code ('shootout'):.............................................................................................259
Using PerformanceTestResult helpers.........................................................................259
Profiling........................................................................................................................260
PerformanceTestHelper API........................................................................................ 261
References and Additional Resources..................................................................................... 261
Packaging Guide...............................................................................................................262
CM Packaging Utilities Cookbook..................................................................................................... 262
App Server CM Packaging Overview.....................................................................................262
Developing Off-site..................................................................................................... 266
Off-site Process................................................................................................266
On-site Process................................................................................................ 267
Guidelines.....................................................................................................................267
App Server CM Packaging Tools....................................................................................................... 268
Post Install Setup..................................................................................................................... 268
Using the extractCMSource.plx Utility...................................................................................268
Display Usage.............................................................................................................. 268
Extract From an App Server....................................................................................... 269
Extract From Release/Patch Install Package............................................................... 269
FW Utility to extract CM sources from Unix environments.......................................269
Using the applyCM Utility......................................................................................................269
Using the create_CM_Release Utility.....................................................................................270
Using the create_CM_Patch Utility........................................................................................ 271
CM System Data Packaging Tools..................................................................................................... 272
CM System Data Packaging Overview...................................................................................272
Extract Process.........................................................................................................................273
Upload Process........................................................................................................................ 274
12
Chapter 1
Oracle Utilities Software Development Kit
Oracle Utilities Software Development Kit is a set of utilities designed to build applications based on Oracle Utilities
Application Framework, the application framework built by Oracle. It provides utilities for implementers to extend
applications without compromising upgradeability. This document describes the Software Development Kit.
This document is divided into the following parts:
The User Guide describes how to use the Software Development Kit to customize products.
The Developer Guide presents information that aid the development process including technical references and
standards.
The Packaging Guide describes the procedures for taking developed code and data to the target environments.
Overview
The Oracle Utilities Software Development Kit is a set of utilities designed to build applications based on Oracle Utilities
Application Framework, the application framework built by Oracle. It provides utilities for base product developers and
implementers to extend OUAF applications without compromising upgradeability. This document discusses the details of
application development using Software Development Kit, including:
The Development Environment section describes the environment that developers work on while using the Software
Development Kit.
The Build Server section describes the procedure for setting up a build server.
The Technical Architecture section describes applications developed on framework. It describes the framework
technical architecture at a high level and then describes its components in detail.
The Meta-data is the core component of applications built on framework. The meta-data section describes the purpose,
structure, and use of the meta-data tables.
The Development Process section contains high level, quick reference guides on common tasks in building applications
based on framework.
The Cookbook section describes the development tasks in detail. The Development Process section contains links to
specific sections in this section.
The Utilities section describes the tools provided with Software Development Kit. These tools include batch programs
and Perl scripts developed to automate several stages of the development process.
Development Environment
Note: Please see the installation guide for instructions on how to set up the Software Development Kit and its
components.
Development Client
Project Repository
The project repository serves the following purposes:
It is the central storage for all completed, unit-tested code.
It provides the environment from which to build the latest state of the project.
It provides the latest state of the project dev app server from which all developers can synchronize with.
It is the source for CM Packaging.
To support these purposes:
It has to be accessible to all developers.
It is set up as a development client, e.g., similar to a development workstation (see Development Workstation below).
Development Workstation
Developers write, generate, compile, and test code on development workstations. A development client is installed for each
project that the developer works on.
The main components of a development client are the following:
Project Dev App Server. Code is developed on and executables built into the project dev app server.
Software Development Kit Client. This is the primary development tool of the Software Development Kit.
Eclipse SDK. This is the Java development tool used in the Software Development Kit.
Directory Structure
Java
A directory structure with a base directory of java is used for Java development, as shown in the following image.
source contains the code that the developer writes or generates that is submitted to the repository. Under this are the
following directories:
com.splwg.cm.domain contains the CM java source code.
sourcegen contains generated code that is necessary to build the project. All files in this structure are generated and
therefore must not be modified manually in any way.
target contains the runtime files created from source and sourcegen. The contents of this directory is what is deployed
as a jar file to the app server. All files in this structure are generated and therefore must not be modified manually in any
way.
Client Directory
The Software Development Kit client directory contains both the Software Development Kit itself and some project-specific
information like the Eclipse workspace.
The location of the Software Development Kit client is stored in the environment variable SPLSDKROOT.
Note: Updates are unique versions of the Software Development Kit and therefore have their own directories.
Note: A separate copy of Eclipse is installed per version of the Software Development Kit client because each version
may have its own set of plug-ins and the plug-ins must be in the plugins directory of Eclipse.
Project Directories
Each project has its own directory.
shortcut Directory
The shortcuts directory contains various scripts used in development.
Versions
Version Number
The Software Development Kit version number has four (4) components, each of which is a number separated from the
other components by a period ("."), as follows:
<component 1>.<component 2>.<component 3>.<component 4>
The first three components together specify the version of the framework it was built for. So it really is:
<framework version>.<Software Development Kit update >
Updates
In between new versions of the framework, versions of the Software Development Kit that contain fixes for bugs may be
released. These versions are called updates and are indicated by a change in the fourth component of the version number.
Updates are full packages of the Software Development Kit. They install as separate applications and appear so to
the operating system. It does not update an existing earlier version to the new version. For example, versions 2.0.6.1,
2.0.6.2, 2.0.10.0, and 2.0.10.1 can all be installed at the same time. And different projects may be on different Software
Development Kit versions.
Generally, it is best for projects to always be on the latest update. But the Software Development Kit allows different
projects to be on different update version s for the following reasons:
Although a very low possibility, there may be incompatibilities between updates. For example, libraries may have
changed.
Having separate installs for each update allows the developers move their projects to the next update on their own pace.
This allows developers to keep their projects on the same version of the Software Development Kit that is used in the
specific implementation. One project may be aggressive by always being on the latest update version, but another project
may stay longer in an older version if it is more difficult to coordinate all developers to move up to the latest update.
Note: The project repository and all developers of a project must always be on the same version of the Software
Development Kit.
Note: Not all projects need to upgrade to the latest update version at the same time. Updating to a new version
requires coordination among the developers for the project, as well as the on-site implementation team and so it may
take more time for some projects to move to the latest update version.
The steps are as follows:
Stabilize the project.
Install the update.
Build Server
Every enterprise has its own software development practices that cover how developers update code, how changes are
tracked and tested and how new releases are created. We generally expect that whatever practices have historically worked
within an organization will continue to work for the implementation of this application. However, a build methodology
was developed that has worked well for managing concurrent changes to the application that is based on the following
principles:
All of the application should work all of the time. Therefore, changing one small part of the application requires that all
of the application be retested.
Bugs are more expensive to fix the longer they stay in a system. This principle has been proven time and time again in
software engineering. This truth mostly owes to the fact that it is easiest to find the offending developer immediately
after he or she broke the system and also that developer has less recollection of how and where the system was broken as
time goes by.
set JAVA_HOME=C:\jdk\jdk1.5.0_10
set ORACLE_HOME=C:\oracle\oracle10203
set CATALINA_HOME=C:\tomcat\apache-tomcat-5.5.20
set COBDIR=C:\Program Files\Micro Focus\Net Express 5.0\Base
set C3P0_JAR_DIR=C:\c3p0\c3p00904\lib
set HIBERNATE_JAR_DIR=C:\hibernate\hib313
setAppserverEnv.bat
Create a file called setAppserverEnv.bat in //C1CM/2.x.x/V2xx_CCB_CM_WIN_TC_ORA/bin with the following
contents:
SET MOD=V2xx_CM_DEMO_DEV_WIN_TC_ORA
SET BUILDSERVER_MAP=U:\%MOD%
SET DEVDIR=C:\splcm\%MOD%
SET BINDIR=%DEVDIR%\bin
SET SPLAPPDIR=%DEVDIR%\splapp\applications
SET ANT_HOME=C:\splcm\V2xx_CM_DEMO_DEV_WIN_TC_ORA\product\apache-ant-1.6.3
SET TOMCAT_VER=5.5.20
SET TOMCAT_PORT=7300
SET DEBUG_PORT=7301
SET PATH=%DEVDIR%\runtime;%PATH%
set ONLINEBILLINI=%DEVDIR%\ect\billdirfile.ini
set ONLINEDOCINI=%DEVDIR%\etc\doc1dirfile.ini
AppServerRefresh.bat
Create a file called AppServerRefresh.bat in //C1CM/2.x.x/V2xx_CCB_CM_WIN_TC_ORA/bin with the following
contents:
@echo off
cd /d %SPLAPPDIR%
call %ANT_HOME%\bin\ant.bat -l %SPLAPPDIR%\log.txt
goto end
:map_error
echo Error: Could not find build server path %BUILDSERVER_MAP%
goto end
:app_error
echo Error: App server path %SPLAPPDIR% not found
goto end
:end
build.xml
Create a file called build.xml in //C1CM/2.x.x/V2xx_CCB_CM_WIN_TC_ORA/ splapp/applications with the following
contents:
</target>
<target name="CheckSavedDir">
<echo message="Checking if saved directory exist..."/>
<condition property="saved.dir.exist">
<available file="${spl.build.saved.dir}" type="dir"/>
</condition>
<echo message="Checking if build server is in the process of saving files..."/>
<condition property="saving.files.in.progress">
<available file="${spl.build.root.dir}\~saving_files" type="file"/>
</condition>
</target>
</project>
JUnit testing
JUnit is a Java framework that supports writing unit tests that help ensure your code works as desired, and existing code
is not broken by new changes. It is often useful to create JUnit tests during development to verify that your code works as
Note: This document assumes that you use Eclipse. However you can choose to use different IDE but then you have
to find how to achieve the equivalent functionality that Eclipse provides.
Assuming you have an existing JUnit test class, you can execute them directly within Eclipse by:
Right-clicking on the class in Package Explorer
Run -> JUnit Test
All the tests for an application can be run from Eclipse by running the com.splwg.AllTests class in the "test" directory
as a JUnit test.
Testing Searches
There is a convenient test superclass for search services, com.splwg.base.api.testers.SearchTestCase. This test
class only requires that you override two methods:
String getServiceName() - this method specifies the service name, eg CILCACCS, for the search
List getSearchTrials() - this method should return a list of SearchTrials
A search trial describes information about a particular invocation of a search. You need to describe the inputs (the input
fields and the search type), and then describe the expected output for that given input:
Some expected rows, in the order expected
In order to properly test searches, the expected results is not required to contain every search result- if new rows are added
by some other process, they will not cause the test to fail. The search results, however, must contain at least all of the
expected results, in the relative order they are added.
Possibly some prohibited rows, which the search should not find
In addition, there may be times when you want to guarantee that a certain row is definitely NOT found in the search result.
This can be accomplished by adding a prohibitedRow, in the same manner as expected rows are added to the trial.
The search test FW will then use inputs from each search trial to execute the search, and compare the expected and
prohibited results to the actual search results. It expects to find the expected rows in the order added, and should find all
of them. Any different order or missing row results in a failure. What will not result in a test failure is if new rows have
been added interspersed throughout the expected rows. These are fine. If a given search result row does not match the next
expected result row, it is compared against all of the prohibited rows. If it matches any of them, the test fails.
The search framework will also examine the information about the search, and ensure that each search type (main, alternate,
alternate2, ...) is executed at least once.
Here is a sample search test class:
package com.splwg.base.domain.batch.batchControl;
import com.splwg.base.api.lookup.SearchTypeLookup;
import com.splwg.base.api.testers.SearchTestCase;
import com.splwg.base.api.testers.SearchTestResult;
import com.splwg.base.api.testers.SearchTrial;
/**
* @author bosorio
* @version $Revision: #2 $
*/
public class BatchControlSearchService_Test
extends SearchTestCase {
/**
* @see com.splwg.base.api.testers.SearchTestCase#getSearchTrials()
*/
protected List getSearchTrials() {
List list = new ArrayList();
trial.addInput(BatchControlSearchService.INPUT_MAIN.BATCH_CD,
"ADM");
SearchTestResult expectedResult = trial.newExpectedResult();
expectedResult.put(BatchControlSearchService.RESULT.BATCH_CD,
"ADM");
list.add(trial);
trial.addInput(BatchControlSearchService.INPUT_ALT.DESCR,
"AcCount D");
expectedResult = trial.newExpectedResult();
expectedResult.put(BatchControlSearchService.RESULT.BATCH_CD,
"ADM");
expectedResult.put(BatchControlSearchService.RESULT.DESCR,
"Account debt monitor");
list.add(trial);
return list;
}
}
listBody.put(Maintenance.STRUCTURE.list_BCP.BATCH_CD, "ZZTEST2");
listBody.put(Maintenance.STRUCTURE.list_BCP.SEQ_NUM,
BigInteger.valueOf(10));
listBody.put(Maintenance.STRUCTURE.list_BCP.BATCH_PARM_NAME,
"param1");
listBody.put(Maintenance.STRUCTURE.list_BCP.BATCH_PARM_VAL, "val1");
listBody.put(Maintenance.STRUCTURE.list_BCP.REQUIRED_SW,
Boolean.FALSE);
listBody.put(Maintenance.STRUCTURE.list_BCP.DESCR50, "Parameter 1");
listBody.prepareToAdd();
return body;
}
(This may look like an awful lot of typing, but any IDE like e.g. Eclipse that offers code-completion will make this kind of
code entry very quick).
If the maintenance performs some server-side "defaulting" (changing of the data), and the result after the add differs from
the data above, you will need to override protected PageBody getNewReadEntity(PageBody original). This
method gets the original data from the method above, and allows manipulation to bring it to the expected form after a read
from the database.
In order to actually perform the read, the read header should be specified in protected abstract PageHeader
getReadHeader(). For example:
Here is an example:
return original;
}
A read is performed after the above changes are sent, and the results are compared.
The input page body should be populated with the expected inputs for the default action, while the output should be
compared against the expected output.
The Comparisons
After the adds and changes above (also a delete is done), the state of the row is compared against the new row. By default,
the framework implementations should work fine, and you don't need to do anything. However, in the rare case, you may
need to override the following methods:
Another example for testing the default on the field which in on the list.
/**
* @see com.splwg.base.api.testers.AbstractEntityTestCase#getChangeHandlerClass()
*/
protected Class getChangeHandlerClass() {
return CharacteristicType_CHandler.class;
}
}
This is a JUnit test case. Let's run it. From within Eclipse, right-click on the test class from within the Package Explorer.
As we see, the tests failed and told us that none of our three validation rules where validated. This is, of course true, but
some explanation is necessary. When we run entity test cases, the framework looks up the change handler class being tested
Here's the test that was added to the test class to test it:
// this should be OK
charType.setDTO(charTypeDTO);
Note: Important note: Both a valid test AND an invalid test were added to the above method.
Finally, when the test is rerun, we have one less validation rule needing to be violated.
HandleRegisteredChange
(BusinessEntity changedBusinessEntity,
RegisteredChangeDetail changeDetail)
handleAdd(BusinessEntity newBusinessEntity)
It is still imperative that this code should also be exercised AND verified when testing the change handler. Please ensure
that every path through these methods is exercised and the results verified.
In general, there is a specific set of classes or functionality that is required to have explicitly defined tests.
Every entity (and entity extension) class must have each of its validation rules explicitly tested. That is, each rule should
fail once, with an explicit acknowledgement of the failed rule expected.
Every service must have a test.
Note: Currently, the above "must have" tests may still not completely cover all the cases. For example, one search
type may have several inputs, which trigger different code or queries to be executed. The testing FW as is can not know
this, so only requires a single test case for that search type. However, it is strongly recommended that each specialized
case possible be modeled with a test case, in order to achieve complete code coverage.
Note: In addition, there is a desire to assure that each business component or business entity method has been tested.
Currently these tests are not required. However, after a complete build server run, any business component methods or
business entity methods that have not been explicitly tested will be reported.
Maintenance Classes
Here is complete valid example of verifying that a maintenance default action issues a proper warning.
disableWarnings();
Note: By default, warnings are enabled, thus nothing special need be done. But you should put the normal try/catch
block around the default execution, and catch an application warning. Once inside the catch block, you should verify
that the warning(s) is/are valid expected ones. (This comparison is only done via the message category and message
number. Thus, if there are parameters to the message construction, it matters not their values, since it may be difficult to
get the values.) You should then retry the default with warnings disabled.
instDto.setBillSegmentFreezeOption
(BillSegmentFreezeOptionLookup.FREEZE_AT_WILL);
installation.setDTO(instDto);
instDto.setBillSegmentFreezeOption
(BillSegmentFreezeOptionLookup.FREEZE_AT_BILL_COMPLETION);
installation.setDTO(instDto);
verifyWarningsContain
(MessageRepository.changeBillSegmentFreezeWarning());
}
Again, by default warnings are enabled, so nothing need be stated at the outset. Additionally, the conversion of warnings to
an exception occurs at a later point, so there is no ApplicationWarning to catch. Instead, after the offending statement (in
this case the setDTO method) you should just verify that the current warnings contain the specified message.
Technical Background
Portability
The system is highly portable to various hardware platforms, as web application servers are pure Java applications and run
on myriad operating systems, including Windows clients, servers, and many versions of UNIX.
In principle, any compliant Java 2 Enterprise Edition container can host the application.
Distribution
The various logical components can be distributed to as many machines as desired. In particular, the web application server
architecture is stateless, so many parallel server machines can be utilized given an appropriate load-balancing architecture.
<?xml version="1.0"?>
<!-- Service CIPBSTMP -->
<page service="CILBSTMP">
The root element of the document has the tag "page" to reflect that this is a page service, and describes the service name as
an attribute.
<pageHeader>
<string name="STM_ID" size="12"/>
</pageHeader>
The <page> element contains exactly one <pageHeader> and one <pageBody>. The <pageHeader> contains any number of
"singleton" fields. This one is a string field named "STM_ID" in the browser, and with the same name in the original Java
source. The field contains up to 12 characters (this is the "business rule" length, not physical storage).
Other types of singleton fields include <bigInteger>, <bigDecimal>, <money>, <date>, <time>, <dateTime>, and
<boolean>.
The number-related fields (<bigInteger>, <bigDecimal>, and <money>) have a "precision" attribute, which describes the
maximum number of digits that can be represented. Further, <bigDecimal> and <money> include the "scale" attribute,
describing the number of decimal digits appearing after the decimal point. Thus, an element like this <bigDecimal
precision="4" scale="2"/> can represent numbers in the range +/-99.99.
Continuing with the page service example, we have this section:
<pageBody>
<row actionFlag="ROW_ACTION_FLG">
<string name="BATCH_CD"
size="8"/>
<bigInteger name="BATCH_NBR"
precision="10"/>
The <pageBody> element contains <row> elements, singleton fields, and <list> elements, in any order. Here we have
another <string> field, as well as a <bigInteger> (an integer value with no decimal fraction), this one holding (up to) 10
digits. This means numbers in the range +/-9,999,999,999 can be represented.
The <row> element reflect the java entity (row). In terms of the infoset and browser the fields in the <row> element are
effectively merged into the containing <pageBody>, along with fields from any sibling <row> elements.
The "actionFlag" attribute names the field that contains a flag that determines the server action that should occur against the
row.
<string name="STM_CNST_ID"
size="10"/>
<date name="STM_DT" />
<string name="STM_ID"
size="12"
isPK="true"/>
<string name="STM_STAT_FLG"
size="2"/>
<bigInteger name="VERSION"
precision="5"/>
</row>
The <list> element describes an elaborately structured array of objects. The element contains exactly one <listHeader>
and <listBody>. Every list within a service buffer has a unique name attribute. The number of possible list body objects is
given by the "size" attribute. In the event a list service exists independently for the list, it is named by the "service" attribute.
Finally the "userGetMore" attribute switches the system into one of two modes:
userGetMore="false" means the system does not require the consent of the user in order to fetch more elements, in the event
that the physical list buffer is filled to capacity with more elements available in the database. The system will autonomously
call the corresponding list service (if it exists) in order to fetch the missing elements. In this way clients making one logical
page service call may result in one physical page and several list service invocations.
userGetMore="true" means the system requires the affirmative consent of the user (e.g. via a "get more" button in the
browser) to continue fetching available data. The list buffer is truncated.
<listHeader lastIndex="STM_DTL_COLL_CNT"
actionFlag="LIST_ACTION_FLG"
moreRows="MORE_ROWS_SW"
alertRowIndex="ALERT_ROW">
<string name="STM_ID"
size="12"/>
<string name="LAST_STM_DTL_ID"
size="12"/>
</listHeader>
The <listHeader> element has a "lastIndex" attribute giving the field name that holds the number of elements actually
returned, an "actionFlag" describing the operation to be performed on the list (e.g. change, delete), the "moreRows" attribute
naming the field that holds the boolean that indicates whether more data remains un-retrieved in the database for the
current list, and the "alertRowIndex" attribute, naming the field that holds an index into the list to describe the location of a
validation error, used to select the correct item in a browser when presenting the error to the user.
In addition, a <listHeader> can contain any number of singleton fields. These are typically keys describing how to access
this list, and logical "cursor" fields describing how to continue fetching more items.
<listBody>
<row actionFlag="ROW_ACTION_FLG2">
<bigInteger name="VERSION"
precision="5"/>
<string name="STM_DTL_ID"
size="12"
isPK="true"/>
<string name="STM_CNST_DTL_ID"
size="10"/>
<string name="STM_ID"
size="12"/>
</row>
<string name="STM_CNST_DTL_DESCR"
size="50"/>
</listBody>
</list>
This finishes the <list> element. Some more singleton elements appear before finishing the <pageBody> and <page>:
<string name="STM_CNST_DESCR"
size="50"/>
<boolean name="ACTION_GENERATE_SW" />
</pageBody>
</page>
<?xml version="1.0"?>
<!-- XML Java/Tuxedo mapping CIPCACCS
Automatically generated by makeXMLMap Sat Nov 10 09:08:30 2001
Source copybooks: CICCACCS CICCACCH -->
<search name="ACCT"
service="CILCACCS"
size="300">
<searchHeader lastIndex="ACCT_COLL_CNT"
actionFlag="SRCH_ACTION_FLG"
searchByFlag="SEARCH_BY_FLG">
The <search> element is the root of the document, and contains a <searchHeader> and <listBody>. The <search> element is
similar to the <list> element described above, and includes name, service, and size attributes. The <searchHeader> includes
the "lastIndex" attribute, which gives the name of the field holding the number of returned elements, "actionFlag" which
names the field containing the search action flag, and "searchByFlag" which names the field holding the search "mode".
The <searchHeader> further contains singleton fields describing search criteria. These are adorned with extra attributes
describing whether they are distinguished criteria that should always be populated from the search client (optional, defaults
to "false"), and a criteria group designation.
<string name="ACCT_ID"
size="10"
isCriteriaExtract="true"
criteriaGroup="MN"/>
<string name="ENTITY_NAME"
size="50"
criteriaGroup="AL"/>
</searchHeader>
The <listBody> was described previously, and describes the structure of the elements matching the search criteria. In
addition, the "isReturn" attribute describes fields that should be returned as the result data when a particular result row is
selected (optional, defaults to "false").
<listBody>
<row actionFlag="ROW_ACTION_FLG">
<string name="ACCT_ID"
size="10"
isReturn="true"/>
<string name="ENTITY_NAME"
size="50"/>
<string name="ACCT_REL_DESCR"
size="50"/>
<string name="NAME_TYPE_FLG"
size="4"/>
</row>
</listBody>
</search>
Introduction
The OUAF browser client uses many novel mechanisms in order to support the system design goals of high system
performance, including low latency and high throughput. The core design principle is that the system is stateless, meaning
only the browser client itself is aware of the session state, that is the application's context--what data is being viewed/
modified and all other information related to a user more typically associated with session state on the server. This
document discusses the important design points that implement a stateless architecture.
It is important to remember that the servlets deal with "pure" model data, and have no visible representation. Since actual
business logic and database access resides in the app server, the servlets take the role of dispatchers and most servlets accept
a "service" parameter describing which app server back-end service to invoke.
The model data is combined with the view on the browser client whenever the model changes or the view needs to be
refreshed. This is done by a name-matching scheme where every HTML element that shows a model value has a name that
"picks out" a corresponding value from the current model. All such HTML fields must include the string "data" in their
HTML class.
The simplest case is showing a value from the "root" object, in which case the field name, also referred to as the "JS name"
simply matches the model's attribute name.
There is more complexity in the case of lists. Every list in the model has a unique name, regardless of nesting depth, so a JS
name that combines the list name with the property name suffices to uniquely identify a section of the model.
There are two sub cases of displaying properties of lists. The first is where the desired index into the list is known (e.g.
grids). In this case, the JS name combines the list name, index, and property name as follows: <LIST_NAME>:POSITION
Overview
The OUAF system offers a large number of useful JavaScript functions in the client (browser). These allow manipulation of
widgets, data, and triggering requests to the Web Application Server to view another page and/or object.
This document discusses functions that developers of user exit functions may wish to use.
CisModel
The CisModel class plays two roles. The first role is to provide the metadata that describes the currently loaded model
instance. The methods that serve this role are static methods, e.g., defined directly on the CisModel prototype object.
These methods are accessible using the syntax CisModel.function(params), assuming you are in the main frame. If not,
use main.CisModel.function(params). Instance methods and variables are, of course, accessible through any instance of
CisModel, e.g. model.pageData or model.getValue('ACCT_ID').
Data representation
The data stored in instances of CisModel uses an internal system representation, not a localized representation. This means
code that manipulates the model is unaware of the user's locale and display preferences. For instance, date values are always
stored using the ISO 8601 string representation YYYY-MM-DD, and numbers are always stored as strings, not JavaScript
numbers (because the required precision may exceed that of JavaScript's native number type).
The data takes the form of a tree of data nodes of two classes, DataElement (the singleton node class holding data attributes
as JavaScript properties), and List, which manages an array of DataElement instances. Every list has a unique name
property, regardless of its position in the tree (e.g. independent of nesting depth), making it possible to uniquely identify
and retrieve any list by its name. The DataElement instances each keep a "dirty" flag to mark whether the user modified any
properties, representing work that needs to be persisted to the database.
Every element instance is always in one of three logical states:
Persistent
New/Dirty
New/Clean (e.g. a "phantom")
Phantom elements are used to populate otherwise empty lists, to give a starting point in which to enter data. Unlike other
new objects, phantoms are initially clean so they don't participate in persistence operations until explicitly modified.
Many CisModel methods act as starting points for recursive implementation through the data tree, and methods with the
same or similar names are available on the DataElement class.
Navigation
Many methods accept list names as arguments in order to operate a unique list instance within the model data tree. Since it
is possible for lists to be nested inside other lists, the system assumes the intended list is the one identified by the "current"
list positions in the ancestor branch.
Static methods
parseNames(fieldName)
This function accepts a string containing a JS field name (the id of an HTML element) and cracks it into its constituent
components: the list name, index, and property. The result is an object with three attributes, property and listName (which
are null if missing), and position, which is actually a function that takes the current list position as an integer argument. The
reason for this is to allow the calculation of the current position (no index) and a fixed index. If the list fragment is missing
the listName and position are both null.
setListPosition(listName, newPosition)
Sets the list identified by the given listName to the position (a zero-based integer value) given by newPosition. Useful when
you want to display a particular element in a scroll.
getList(listName)
Answers the list object (instance of List) with the given name.
replaceWithNewList(listName, sourceModel)
Typically called from the default handler callback, this method replaces the entire contents of the given list in the receiver
(e.g. the model whose method is being called) with the list as provided in sourceModel. All elements in the list are
considered new, and are eligible to be added to the database when the Save button is used.
hasRealElements(listName)
Answer a boolean indicating whether the indicated list contains any persistent or dirty elements (not merely a single
phantom).
getElement(fieldName)
Returns the data element (instance of DataElement) corresponding to the given field name. The method resolves the list
name and position index, if any, in order to navigate to the appropriate data element.
markAsNew()
Mark the model "clean" by recursively clearing all dirty flags throughout the tree structure. Note this is a very "sensitive"
method and should only rarely be needed.
DataElement
Instances of DataElement play the role of the nodes in the data model tree. They have properties corresponding to business
attributes, and also define the tree structure by holding references to their parent data element and list(s) of children
elements. The distinguished root DataElement instance in the core model instance is accessed using with the "pageData"
property.
List
Instances of List represent a collection of DataElement instances, held by a parent DataElement. Every List is held by a
DataElement, but the pageData "root" node has no parent list (it's held directly by the model).
Free Functions
top.js
This is the set of "free" functions available in top.js, which is included by cis.jsp. You typically access these functions using
the top.xyz() syntax, assuming your code is running in an iframe nested under cis.jsp.
The trend has been to de-emphasize the use of functions at this level, and migrate them to the main level. In the future we
plan to eliminate the distinction between the top and main frames.
getNavigationKeyForService(service)
Answers the navigation key corresponding to the given service (string). Since there may be several nav keys for the same
service, the last one is answered. You always get the correct response for tab menus.
getURL(navigationKey, withoutLanguage)
Answer the URL (string) corresponding to the given navigation key (also a string). If the withoutLanguage boolean is false,
the user's language code is appended to the URL as a GET parameter.
getFieldLevelSecurityInfo(navigationKeyOrService)
Answer the field-level security meta-data for the tab menu given by the navigation key or service. The result takes the form
of a simple JavaScript object, with security types as properties, and values as arrays of all related authentication levels. For
example, assume that adjustment maintenance has field-level security defined for a user for security type "ADJAMT", with
two associated authentication levels, "1", and "3". To retrieve the object defining all field-level security info for the service:
cis.js
The cis.js file contains the bulk of the core framework functions. In addition to defining the major framework classes
(CisModel, DataElement, List, etc.) it contains a number of important functions that are described here. These functions are
typically invoked by navigating to the main level, e.g. main.xyz(), where the global main has been defined to point to the
frame containing cisMain.jsp.
array_remove_element(array, element)
Remove the indicated element from the given array. Do nothing if it is not found. If the element appears more than once in
the array, remove only the first one. Uses simple object comparison (==).
array_index_of(array, element)
Return the index (0-based) of the given element in the given array. Answer -1 if the element cannot be found. If the element
appears multiple times, answer the first (lowest) index. Uses simple object comparsion (==).
Note: The tab menu is represented by program component in the ERD above.
Every framework user interface (UI) transaction has a tab menu, which links together the different tab pages that are
available on the transaction.
The Software Development Kit generator creates the tab menu using a specific template that is defined in the template
meta-data. The tab menu's template is maintained from the UI Program Components Object View.
The generated tab menu resides in a certain physical directory in the server's file system. Location, the abstract name that
represents the actual location of the tab menu, is entered in the UI Program Components Object View. The actual location
information and the abstract name are maintained from the Locations Object View.
Tab menus may have one or more program variables that control its behavior and/or appearance. These variables are
maintained from the Program Variable Collection of the UI Program Components Object View.
Note: The UI program component is represented by program component in the ERD above.
Each tab that is specified on the tab menu is linked to a particular UI program component - more commonly referred to as
"UI page" or "tab page".
Every UI Program Component has a type (e.g. Search Page, List Grid, etc). The Software Development Kit generator uses
this information to know how to create a certain type of program. The types are stored in the template meta-data table.
Just like tab menus, the generated tab page resides in a certain physical directory in the server's file system. Location, the
abstract name that represents the actual location of the program, is specified in the UI Program Components Object View.
Tab pages may have one or more program variables that control its behavior and/or appearance. These variables are
maintained from the Program Variable Collection of the UI Program Components Object View.
Each tab page has at least one program section. Each section has at least one element of a particular type. A program
element may have one or more element attributes that control its behavior and/or appearance. For example, an element
attribute may specify whether or not a field is hidden. Elements may be as simple as input text fields or buttons, and as
Table-Related Meta-data
Note: Developers should not use plain text on the UI. All labels should be defined as work fields so that the system
will recognize the field and obtain the correct, language-based description to display.
Note: Oracle recommends that customers using Oracle Utilities Application Framework version 4.2 or later and
currently using ConfigLab switch to Configuration Migration Assistant (CMA) for their configuration data migration
needs and retain ConfigLab for migration of master and transaction data migration. Also note that CMA functionality
is not available to every Framework-based product. For details, including tips and requirements for moving from
Please refer to the System Table Guide for the standard naming convention of each Meta-data object below.
Compliance to the standard naming conventions is critical in ensuring the ability to upgrade.
Setting up Fields
Fields meta-data is maintained via the Fields Menu Item from the Admin Menu. Fields may describe columns on a table or
they may be labels or work fields that do not appear on a table.
Fields - Main
Select Fields from Admin Menu to navigate to the Fields View. Field Metadata can be edited in the Main Tab
A field's label can be overridden for a specific table. If this is the case and you change the field's name on this
transaction, the change will have no effect when the field is displayed for that specific table. If you find this to be true,
change the field's label on the respective table on which it was overridden. You do this using the Table Maintenance
transaction (for details see the Oracle Utilities Application Framework Administration Guide).
Properties Description
Open this page using Admin Menu, Field.
Many fields on this page are protected as only the product development group may change them. The following describes
fields you may change for records that are part of the base product. Fields containing information that may be of interest are
also described.
Field Name uniquely identifies this field.
Fastpath: If you introduce new fields, you must prefix the field with CM. If you do not do this, there is a possibility
that a future release of the application could introduce a new field with the name you allocated.
Owner indicates if this field is owned by the base package or by your implementation (Customer Modification). The
system sets the owner to Customer Modification when you add a field. This information is display-only.
Base Field
Data Type indicates if the field will hold Character, Date, DateTime, Number, Time, or Varchar2 data.
Ext Data Type
Precision defines the length of the field. In the case of variable length fields, it is the maximum length possible.
Scale
Sign
Level
88 Cpybk
Description contains the label of the field. This is the label of the field that appears on the various pages on which the field
is displayed. Note, the field's label can be overridden for a specific table (by specifying an Override Label on the table/field
information; for details see the Oracle Utilities Application Framework Administration Guide).
Java Field Name
Override Label
Check Work Field if the field does not represent a database table column.
Help Text
Special Notescontains any notes or special information about the field.
FK References
Select FK Reference from Admin Menu to navigate to the Foreign Key References Window. The Main tab of the FK
References Window maintains the meta-data related to foreign key references on the FK References List.
Note: Context Menu Name. This attribute is only applicable to user interface elements utilizing the foreign key
compound element type. Report parameters that reference foreign key characteristics are an example.
Use Search Navigation Key to define the search page that will be opened when a user searches for valid characteristic
values.
Use Search Type to define the default set of search criteria used by the Search Navigation Key's search page.
Use Search Tooltip to define a label that describes the Search Navigation Key's search page.
Note: Search Type and Search Tooltip. These attributes are only applicable to user interface elements utilizing the
foreign key compound element type. Report parameters that reference foreign key characteristics are an example.
Where Used
Follow this link to open the data dictionary where you can view the tables that reference CI_FK_REF.
Lookup Tables
Select Admin Menu, Look Up to maintain lookup values.
Note: If you wish the override descriptions of your lookup values to appear in the application viewer, you must
regenerate the data dictionary application viewer background process.
Owner Indicates if this lookup value is owned by the base package or by your implementation (Customer Modification).
The system sets the owner to Customer Modification when you add lookup values to a field. This information is display-
only.
In order to improve response times, navigation options are cached the first time they are used after a web server is
started. If you change a navigation option and you don't want to wait for the cache to rebuild, you must clear the cached
Note: You may not change navigation options that are owned by the base package.
Use Navigation Option Type to define if the navigation option navigates to a Transaction or launches a BPA Script.
For navigation option types of Transaction, enter the related information:
Note: Finding transaction navigation keys. When populating the Target Transaction and Search Transaction you
are populating an appropriate navigation key. Because the system has a large number of transactions, we recommend
using the "%" metaphor when you search for the transaction identifier. For example, if you want to find the currency
maintenance transaction, enter "%currency" in the search criteria.
Search Group is only visible if the Development Tools module is not turned off. It is used to define the correlation
between fields on the search page and the tab page. You can view a tab page's Search Groups by viewing the HTML
source and scanning for allFieldPairs.
For navigation option types of script, indicate the Script to launch. You can use the Context Fields at the bottom of the
page if you want to transfer the contents of specific fields to temporary storage variables available to the script. The script
engine creates temporary storage variables with names that match the Context Field names.
The Go To Tooltip is used to specify the label associated with the tool tip that appears when hovering over a Go To object.
Refer to Usage grid below.
The Usage grid defines the objects on which this navigation option is used:
Choose Favorites if the navigation option can be used as a favorite link.
Choose Menus if the navigation option can be used as a user's home page or as a menu or context menu item.
Choose Script if the navigation option can be used in a script.
Choose Foreign Key if the navigation option can be used as a foreign key reference.
Choose Go To if the navigation option can be used as a "go to" destination ("go to" destinations are used on Go To
buttons, tree nodes, algorithm parameters, and hyperlinks).
Choose Notification Upload Type if the navigation option can be used on a notification upload type.
If you have Oracle Utilities Customer Care and Billing, you may choose Campaign if the navigation option can be
used as a "post completion" transaction on a campaign. For more information refer to that product's documentation for
campaigns.
The Context Fields grid contains the names of the fields whose contents will be passed to the Target Transaction
or Script. The system retrieves the values of these fields from the "current" page and transfers them to the target
transactionor to the script's temporary storage.
Setting up Services
This object view defines the available services.
Services
Select Admin Menu, Service Program to maintain service programs.
If you introduce new services, you must prefix them with CM. If you do not do this, there is a possibility that a future
release of the application could introduce a new service name with the name you allocated.
Owner indicates if this service is owned by the base package or by your implementation (Customer Modification). The
system sets the owner to Customer Modification when you add a service. This information is display-only.
Description describes the service.
Service Type indicates whether the service is a Java Based Service.
This Program Component grid shows the list of program user interface components associated with the service. For a
stand-alone XAI service this list is optional.
Where Used
Follow this link to open the data dictionary where you can view the tables that reference CI_MD_SVC.
Setting up Tables
This object view is used to maintain meta-data related to a table. A table represents a database table used to store framework
data or a database view.
Note: Many fields cannot be changed. You cannot change most attributes on tables that are owned by the base-
package (e.g., those whose Owner is not Customer Modification).
Description contains a brief description of the table.
System Table defines if the table holds rows that are owned by the base-package.
Enable Referential Integrity defines if the system performs referential integrity validation when rows in this table are
deleted.
Data Group ID is used for internal purposes.
Table Usage defines how the table is used in the application. In the current release, only tables that are part of Oracle
Utilities Business Intelligence make use of this field.
Table Type defines if the table is a View or a physical Table.
Note: View the source. If the program is shipped with the base package, you can use the adjacent button to display
the source code of this program in the source viewer or Java docs viewer. For details, see "Source Code Viewer" and
"Java Docs Viewer" sections in the Oracle Utilities Application Framework Administration Guide.
Upgrade controls what happens to the rows in this table when the system is upgraded to a new release:
Keep means that the rows on this table are not touched during an upgrade
Merge means that the rows on this table are merged with rows owned by the base package
Refresh means that the rows on this table are deleted and refreshed with rows owned by the base package.
Data Conversion Role controls if/how the table is used by the conversion tool:
Convert (Retain PK) means that the table's rows are populated from the conversion schema and the prime key in the
conversion schema is used when the rows are converted is not assigned by the system.
Convert (New PK) means that the table's rows are populated from the conversion schema and the prime key is
reassigned by the system during conversion.
Not Converted means that the table's rows are not managed by the conversion tool.
View of Production means that the conversion tool uses a view of the table in production when accessing the rows in
the table. For example, the customer class table would be set up using this value so that the conversion tool will use the
customer classes in production when it needs to access customer class codes.
A Language Table is specified when fields containing descriptions are kept in a child table. The child table keeps a
separate record for each language for which a description is translated.
Enable Data Dictionary defines if the table is to be included in the Data Dictionary application viewer.
A Key Table is specified when the prime-key is assigned by the system. This table holds the identity of the prime keys
allocated to both live and archived rows.
Type of Key specifies how prime key values are generated when records are added to the table:
Other means a foreign-system allocates the table's prime-key (e.g., the fact and dimension tables within Oracle Utilities
Business Intelligence have their keys assigned by Oracle Warehouse Builder).
Sequential means a sequence number is incremented whenever a record is added to the table. The next number in the
sequence determines the key value.
System-generated means a program generates a random key for the record when it is added. If the record's table is the
child of another table, it may inherit a portion of the random number from its parent's key.
User-defined means the user specifies the key when a record is added.
Inherited Key Prefix Length defines the number of most significant digits used from a parent record's primary key value
to be used as the prefix for a child record's key value. This is only specified when the Type of Key is System-generated and
the high-order values of the table's key is inherited from the parent table.
Help URL is the link to the user documentation that describes this table.
Special Notes contains any notes or special information about the table.
The grid contains an entry for every field on the table. Drilling down on the field takes you to the Table Field tab where
you may modify certain attributes. The following fields may also be modified from the grid: Description, Override Label,
Audit Delete, Audit Insert and Audit Update. Refer to the Table Field tab for descriptions of these fields.
Tables - Constraints
Select Admin Menu, Table and navigate to the Constraints tab to view the constraints defined on the table.
Note: Additional Conditional SQL Syntax. When specifying additional conditional SQL text, all table names are
prefixed with a pound (#) sign.
The Constraint Field grid at the bottom of the page is for maintaining the field or set of fields that make up this constraint.
Field The name of the table's field that is a component of the constraint.
Sequence The rank of the field as a component of the constraint.
The Referring Constraint Field grid at the bottom of the page displays the field or set of fields that make up the Primary
key constraint of the referring constraint.
Field The name of the table's field that is a component of the referring constraint.
Sequence The rank of the field as a component of the referring constraint.
Setting up Menus
This meta-data represents the root of a menu "tree". A menu contains a list of menu "lines", which, in turn, contains a list of
menu "items". Lines can define navigation keys and/or associated actions, or further submenus.
Menus - Main
This transaction is used to define / change any menu in the system. Navigate to this page using Admin Menu, Menu.
Menus - Main
Description of Page
Enter a meaningful, unique Menu Name.
Owner indicates if this menu line is owned by the base package or by your implementation (Customer Modification). The
system sets the owner to Customer Modification when you add a menu line. This information is display-only.
The Flush Menu button is used to flush the cached menu items so you can see any modified or newly created menus. For
details, see "Caching Overview" in the Oracle Utilities Application Framework Administration Guide.
Menu Type defines how the menu is used. You have the following options:
The following is an example of a menu line with a single item that opens a submenu:
Note: Owner indicates if this menu line is owned by the base package or by your implementation (Customer
Modification). The system sets the owner to Customer Modification when you add a menu line. This information is
display-only.
Note: Oracle recommends that customers using Oracle Utilities Application Framework version 4.2 or later and
currently using ConfigLab switch to Configuration Migration Assistant (CMA) for their configuration data migration
Note: You can add new option types. Your implementation may want to add additional maintenance option types. For
example, your implementation may have plug-in driven logic that would benefit from a new option. To do that, add
your new values to the customizable lookup field MAINT_OBJ_OPT_FLG.
Development Process
This chapter provides a quick reference for common development tasks. The details are described in the Cookbook chapter.
Maintenance extensions
Not all maintenance logic can go in the initial application's Maintenance. For instance, how can you retrieve the description
of a foreign key whose table does not exist in that application?
An "extension" methodology exists whereby an existing page can have behavior added to it at predetermined plug-in points.
This is done by having a list of maintenance extensions that can be supplied for any given maintenance. At runtime, this list
is kept and when a maintenance is initialized, new instances of its extensions are created. These extensions are called after
any original maintenance behavior, and in the order of loaded applications. This means that the extensions should have no
dependence on what other extensions have run, excepting the original maintenance having run.
To extend a maintenance:
Create a new maintenance extension class.
Specify the annotations required for a maintenance extension.
Code desired logic in appropriate methods (see AbstractMaintenanceExtension).
Generate artifacts.
Code JUnit tests.
Run JUnit tests.
Deploy to runtime.
Test in runtime.
/**
* Component used to query for {@link Person} instances based on various
* predefined criteria.
*
* @BusinessComponent
* (customizationReplaceable = false)
*/
public class PersonFinders_Impl
extends GenericBusinessComponent
implements PersonFinders
/**
* @param nameType a name type
* @return count of names by name type
*
* @BusinessMethod (customizationCallable = true)
*/
public int findCountByNameType(Lookup nameType) {
Query query = createQuery
("FROM PersonName name where name.nameType = :type");
query.bindLookup("type", nameType);
Plugging in Algorithms
Algorithms provide a powerful and flexible way of extending applications that use the Oracle Utilities Software
Development Kit.
Algorithm spots in the application identify different areas that can be extended or customized by implementers. Each
algorithm spot defines a set of inputs (typically via set- methods) and output (typically by get- methods).
During implementation, implementers can either re-use existing algorithm types or create new plug-in algorithm. To add a
new plug-in algorithm, an implementer will follow these steps:
Identify the plug-in spot.
Generate CM Javadocs
Prerequisite: all artifacts need to be generated and the code needs to be compiled without errors.
The first step is to generate Javadocs for CM code. The standard behavior of the Javadoc tool is to create indices that show
the packages and classes of the source code that the tool was run on. The resulting indices will only show links to the CM
classes and not the product's. To recreate the indices so that they include both the CM and the product's Javadocs, follow the
next step.
Cookbook
Maintenance extensions
Not all maintenance logic can go in the initial application's Maintenance. For instance, how can you retrieve the description
of a foreign key whose table doesn't exist in that application?
Therefore, an "extension" methodology needs to exist whereby an existing page can have behavior added to it at
predetermined plug-in points.
/**
* @version $Revision: #1 $
* @MaintenanceExtension (serviceName = CILTALTP,
* newDefaults={ @JavaNameValue (value = TEST, name = test)
* }
* )
*/
public class AlgorithmTypeMaintenanceExtension
extends AlgorithmTypeMaintenanceExtension_Gen {
}
The maintenance extension will have its superclass generated to give easy access to the STRUCTURE definition and
HEADER and DEFAULT constants, as well as provide an easy hook for any future functionality that might need to be
inserted.
You must use the constants on the STRUCTURE or HEADER structure definitions to reference input header fields or
which output fields to populate.
The maintenance extension can then override any methods needed to provide its functionality. Some examples of methods
available are:
/**
* Process a default
* @param defaultValue the raw string value of the default (can compare
* against DEFAULTS constants)
* @param item the item to be modified with default values
*/
public void processDefault(String defaultValue, DataElement item) {}
/**
* Process the data after the whole add (root and chidren) action is
* done.
* @param originalItem the input item
*/
public void afterAdd(DataElement originalItem) {}
/**
* Process the data after the whole read (root and children) action is
* done.
* @param result the output item
*/
public void afterRead(DataElement result) {}
/**
* Process the data after an element of the given list has been read.
* @param listName the list name
* @param outputElement the output element
* @param sourceEntity the just read entity
*/
public void afterPopulateElement(String listName,
DataElement outputElement, BusinessEntity sourceEntity) {}
// ...
The complete list can be found in the hierarchy of the extension class (e.g., AbstractMaintenanceExtension) http://
www.python.org/
function focusWidgetOverride() {
return null;
}
function focusWidgetOverride() {
return "TD_TYPE_DRLKY:0$TBL_NAME";
}
function focusWidgetOverride() {
return "LAST_NAME";
}
Note: These functions can be as simple or complicated as you want. You could conditionally return a field name or
null and this code will run each time the window loads. Also, if a tab page has a popup window or a search window
open as it is loading then the initial focus will not be set to the tab page but stay with the popup window
function ignoreModifiedFields(){
return ['START_DTTM']
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 100
function overrideDefaultTriggersFor_SRCH1() {
var triggers = {};
triggers["ACCT_ID"] = true;
triggers["SA_ID"]=true;
return triggers;
}
function notUppercaseFields() {
return ['ELEM_ATT$AT_NAME']
}
You can also provide a "global" override for an entire TabMenu by setting the shouldNotAutoUppercase variable to true:
function saveButtonEnablingOverride() {
return false;
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 101
Example :
function privatePostAddSucceeded() {
var model = parent.model;
var modeFlag = model.getValue('COMPL_NAV_MODE_FLG');
var navKey = model.getValue('COMPL_NAV_KEY');
var complSw = model.getValue('CMPLT_CLICKED_SW');
if (complSw && model.getValue('ENRL_STATUS_FLG') == '30') {
if (modeFlg && navKey){
if (modeFlag == 'G') {
parent.tabPage.gotoContext(navKey);
return false;
} else if(modeFlag == 'A') {
parent.tabPage.addContext(navKey);
return false;
}
}
}
return true;
}
How Do I Prevent Attributes From Being Copied into New List Elements?
The system automatically copies key fields (based on name matching) from a parent list element into new child elements
(e.g. created by using the scroll '+' button), in order to keep their prime keys consistent. If you want to inhibit this operation
for certain fields, define the TabMenu function dontCopyKeyNames_<LIST NAME> to return an array of fields that should
not be copied into new elements of the list named LIST_NAME
Example:
function dontCopyKeyNames_ENRL_FLD() {
return ['SEQ_NUM']
}
function initializeNewElement_ENRL_LOG(newElement) {
newElement.set('ENRL_LOG_TYPE_FLG', 'USER');
newElement.set('USER_INFO', parent.model.getValue('CURRENT_USER_INFO'));
Oracle Utilities Application Framework Software Development Kit Developer's Guide 102
}
Note: The default Sequence Number functionality will default the next nearest tens value from the highest sequence.
The defaulting will do nothing after the sequence reaches the highest number it can hold.
In the user exit file of the Tab Menu - not the main Page or the List Grid - copy this JavaScript code:
function initializeNewElement_LIST_NAME(newElement) {
var myListName = "LIST_NAME";
var myListSeqName = "FIELD_NAME";
var myListMaxSeq = 999;
defaultSequenceNumber(myListName,myListSeqName,myListMaxSeq,newElement)
}
</SCRIPT>
<SCRIPT src="/zz/defaultSequenceNumber/defaultSequenceNumber.js"></SCRIPT>
<SCRIPT>
For LIST_NAME, substitute your List Grid's list name. Be careful not to lose that underscore [ _ ] just in front of LIST_
NAME in the first line! Remember that JavaScript is case-sensitive and make sure that you use all UPPERCASE letters
as shown here.
For FIELD_NAME, substitute the name of your sequence field, whatever that might be in your List. Don't lose the
quotes [ " ] ! Again, use all UPPERCASE letters.
How Do I Override the Tab Page Shown After an Error in a List (Grid/
Scroll)?
When the system receives an error (e.g. after a Save) it attempts to set focus on the relevant widget, which might
require flipping to a different tab page. If the error relates to a list (grid or scroll) the system might not choose the tab
page you'd prefer. In that event you can control the tab page that should be opened by defining the TabMenu function
overrideErrorTabPage_<LIST_NAME>().
Example:
function overrideErrorTabPage_BPA() {
return 'bussProcessAssistantStepPage';
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 103
define the function addIgnoreFieldsFor_<triggerFieldName>() on a tab or search page's user exit file to specify fields to
ignore whenever the IMG button named triggerFieldName is pushed on that page.
The function takes a single argument, fields, and you should add key/value pairs where the key is a field name to ignore,
and the value is true.
Example:
addIgnoreFieldsFor_ADDRESS1_SRCH = function(fields) {
fields['CITY_SRCH'] = true
}
addIgnoreFieldsFor_PER_ID = function(fields) {
fields['ENTITY_NAME_SRCH'] = true
}
function ignoreResultColumns() {
return { ADDRESS1: true, CITY: true, POSTAL: true };
}
Since Searches can be shared by many search clients, it is possible that some clients want to get a specific column, but
others don't. In that case, define the TabMenu function ignoreResultColumnsFor_<service> as above.
Example:
function ignoreResultColumnsFor_CILCCOPS() {
return {CONT_OPT_TYPE_CD: true}
}
</SCRIPT>
<SCRIPT src="/zz/formatValue/formatValue.js"></SCRIPT>
<SCRIPT>
Now, you can start using the function to format a value. To use this function, you need to pass in both the value and the
format into the function.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 104
if (pureFieldName == 'PHONE') {
updateField(pureListName + 'PHONE' ,
formatValue(myData.getValue(pureListName + 'PHONE'), phFormat));
}
Note: Note: CM interceptors defined on the CMServiceConfig.xml override base product interceptors on the same
service and action.
To implement an interceptor:
Creating a class implementing any of the Interceptor Java Interfaces.
Register the class in CMServiceConfig.xml.
Example
The following is a sample interceptor and configuration file, where one interceptor class implements all four interfaces.
Configuration file CMServiceConfig.xml:
<ServiceInterceptors
<Service name="CMLTBTCP">
<Interceptor action="add">
com.splwg.cis.interceptortest.InterceptorTest
</Interceptor>
<Interceptor action="change">
com.splwg.cis.interceptortest.InterceptorTest
</Interceptor>
<Interceptor action="delete">
com.splwg.cis.interceptortest.InterceptorTest
</Interceptor>
<Interceptor action="read">
com.splwg.cis.interceptortest.InterceptorTest
</Interceptor>
</Service>
</ServiceInterceptors>
Class com.splwg.cm.interceptortest.InterceptorTest:
package com.splwg.cm.interceptortest;
import com.splwg.base.api.serviceinterception.IAddInterceptor;
import com.splwg.base.api.serviceinterception.IChangeInterceptor;
import com.splwg.base.api.serviceinterception.IDeleteInterceptor;
import com.splwg.base.api.serviceinterception.IReadInterceptor;
import com.splwg.base.api.service.PageBody;
import com.splwg.base.api.service.PageHeader;
import com.splwg.base.api.service.RequestContext;
Oracle Utilities Application Framework Software Development Kit Developer's Guide 105
public PageBody aboutToAdd(RequestContext context, PageBody in) {
System.out.println("aboutToAdd: " + in);
return null;
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 106
modules = { "foundation"})
This example doesn't use any lists, but they are described and supported as are any entity maintenance classes. By
definition, any lists here are unmapped--that is, they are not populated by the framework from the entity model.
The supported actions are read, change, add, and delete. You can leave out the actions annotation completely if you
intend to support all four of these actions. Otherwise, it's useful to declare what methods you'll support, so the framework
can create an appropriate error message when an unsupported method is invoked.
You must implement one or more of the following action methods.
The body of the implementation is completely up to you. The available API is largely the same as for entity page
maintenance, e.g. you have a current session/transaction in which to execute queries, can access the entity model, etc.
You are expected to throw ApplicationError or ApplicationWarning Java exceptions, as appropriate (e.g. via
addError() and addWarning()), unless a serious or unforeseen problem occurs, in which case you should throw a
LoggedException, or simply let the underlying Java runtime exception "bubble up".
The usual implementation of the read method would be to retrieve one or more parameters from the input page header, and
construct a DataElement holding the desired return values, including any lists (which may be recursive).
For the change method, the usual behavior would be to examine the provided DataElement object, perform some
operation, and return a different data element to hold the "changed" values.
The add method is similar to change in that it accepts an input DataElement, and returns the "newly added" DataElement
instance (which should be a different instance than the input).
The delete method accepts a DataElement, but returns nothing after the conclusion of the operation.
Maintaining MOs
@EntityPageMaintenance (
program = CIPTBTCP,
service = CILTBTCP,
entity = batchControl,
copy = true,
body = @DataElement (
contents = {@DataField (DEFAULT_FOR_FLG)
, @RowField (name=foo, entity=batchControl)
, @ListField(name=BCP, owner=foo, property = parameters)
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 107
),
lists = {@List (name = BCP, size = 50, copy = true,
program=CIPTBCPL, constantName="CI-CONST-CT-MAX-FIFTY-COLL",
body = @DataElement (contents = {@RowField
(batchControlParameter)}))
}
)
First we see that this tag is an EntityPageMaintenance, meaning it is a page maintenance for a single entity root object.
Here it is a batch control, but account, person, premise, etc. would also be examples. The idea here is that, by default, the
maintenance framework tries to read, save, and delete the tree of data that starts with an instance of batch control. (Another
kind of page maintenance is EntityListPageMaintenance, where you maintain a list of entities without a single root object. It
has slightly different attributes than those discussed below.)
Next we list some attributes of the top-level annotation. The required program attribute gives the equivalent COBOL page
module name that we're replacing. That's going to become important later when we create COBOL stubs to call back into
Java from COBOL code that wants to call this maintenance, which will no longer be available as a COBOL implementation.
The service is the name of the page service that we are implementing. This is required so the framework knows that it
should route requests for this service directly to this java class rather than invoking Jolt/Tuxedo/COBOL.
The required entity property names the entity that this maintenance uses for its root. It should match an entity that is
defined within the system, else the maintenance obviously can't work!
The copy attribute signals that certain copy fields should be defined in the service. Making the framework explicitly aware
of these fields is preferable to "dumb" coding of these fields.
Now we hit the two major structural elements, the body and lists attributes.
The body attribute always resolves to a DataElement, which is simply a way to organize the collection of "rows", "loose
fields", and lists that belong to a particular level in the service data structure. These contents are simply held in the
contents array, which here starts with a simple datafield, DEFAULT_FOR_FLG. Note that you simply reference the field
name, and the generator uses the field metadata to infer its type and size. The next element of the contents array in this
example is RowField. This is essentially a way of naming a reference to the properties of a single entity/table, including
its language fields, if appropriate. You need to specify its entity and name. Here I use a dummy name, "foo". Finally we
have a ListField, which consists of a reference to a list structure that is defined in a separate tag (lists). Here we merely
name the referenced list by name, provide the owner which matches the name of the "parent" row, and the property, which
tells the system how to access the list from the parent. Here we deduce that the getParameters() method on a batch
control will yield the desired child list.
package com.splwg.base.domain.batch.batchRun;
import com.splwg.base.api.service.ListHeader;
Oracle Utilities Application Framework Software Development Kit Developer's Guide 108
import com.splwg.base.api.testers.ListServiceTestCase;
import java.math.BigInteger;
/**
* @see com.splwg.base.api.testers.ListServiceTestCase#getReadListHeader()
*/
protected ListHeader getReadListHeader() {
ListHeader header = new ListHeader();
header.put("BATCH_CD", "TD-BTERR");
header.put("BATCH_NBR", BigInteger.valueOf(1));
header.put("BATCH_RERUN_NBR", BigInteger.valueOf(0));
return header;
}
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 109
An example of using this filtering to join extra information is available on the class MaintenanceObjectMaintenance.
Another example on a ListService, is available on the class NavigationOptionMenuList.
Besides using a MaintenanceListFilter and knowing how to deal with list get mores, lists in a page maintenance will
automatically retrieve (and cache) the language row associated with the main row of the list. This helps the n+1 select
problem (only a single SQL is issued, instead of the main one, plus an extra one for each of the rows' language row), and
also provides the ability to have short hand for the orderBy property of a list. If the order is simply by a language property,
then you can reference it by thisLang.property, without having to supply a filterClause.
Note: For detailed information about Maintenance Objects, please refer to user document Framework Administration,
Database Tools, Defining Maintenance Object Options
Maintaining Fields
Field represents a column on a database table. A Field must exist before it can be defined on a Table.
Note: For detailed information about fields, please refer to user document Framework Administration, Database
Tools, Defining Field Options.
Maintaining Tables
Table represents a database table used to store data or a database view.
Note: For detailed information about menus, please refer to user document Framework Administration, Database
Tools, Defining Table Options.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 110
Business Entity Background
A central framework concept is the Business Entity that allows for persistent data in the database to be interacted with as
objects. In general there is at least one Business Entity class corresponding to each table in the system. Likewise an instance
of one of these classes corresponds to a row in the database. Here are some things to remember about Business Entities:
When you create a new instance of a Business Entity and the current transaction commits, a new row is committed to
the database. Likewise when instances are deleted or changed, corresponding deletes or updates are performed on the
database. There is no concept of a transient entity in our architecture; application logic is dealing with only persistent
objects.
When the actual insert, update and delete statements are issued to the database is controlled by the framework and may
be deferred for performance reasons. The framework is, however, expected to issue DML with sufficient timeliness to
maintain data consistency so that application code need not concern itself with when statements are actually executed.
When you use the query language (HQL) the returned objects are Business Entities (or scalars in the case of "count" or
other aggregate functions). These objects may be modified by application code and those changes will be persisted to the
database.
The way you change the properties on entities is via the Data Transfer Objects corresponding to the entity.
Alternatively, if you find that you have a reference to an Id class, the appropriate DTO can be created via a method
generated onto that Id class.
Now let's set some values for the new Person instance:
personDTO.setStateId(state.getId());
personDTO.setLanguageId(language.getId());
Finally we try to create a persistent instance based on these values. This is equivalent to doing the insert against the
underlying table except that: (1) required validation occurs and (2) the timing of actual insert occurs at the discretion of the
framework.
That's it. When the current transaction is committed, a new person will be added to the database.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 111
How Do I Change Values on an Existing Business Entity Instance?
There are really three steps:
Ask the existing entity for its DTO.
Change the appropriate values on the DTO.
Call setDTO() on the entity instance.
person.delete();
2. Delete an instance where you have only its Id:
delete(personId);
3. Delete the results of a query
Persistent Classes
Behind the scenes, the persistence and validation mechanisms are quite complex and require the collaboration of many
classes and pieces of configuration data. Thankfully, most of this complexity is hidden from the application programmer.
Still, there are various classes that the application programmer will deal with:
Framework Classes that act as an application programming interface. These API classes are directly referenced by
application code.
Generated Classes that are created for each business entity that serve two purposes:
They provide convenient methods (like property "getters" and "setters") based on the structure of the specific entity,
it's fields, child collections and key structure for example.
They are necessary for the persistence mechanisms to work correctly.
Handcoded classes that the application programmer is expected to write. Many of the handcoded classes are read by the
artifact generator so the framework can "wire up" the handcoded functionality.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 112
Some examples of the above classes are shown below.
/**
* @BusinessEntity
* (tableName = CI_PER,
* oneToManyCollections = { @Child( collectionName = names,
* childTableName = CI_PER_NAME,
* orderByColumnNames = { SEQ_NUM } )
* }
* )
*/
public class Person_Impl
extends Person_Gen {
/**
* @return the UI Display "info" for this person
*/
public String getInfo() {
return "PrimaryName: " + getPrimaryName().getInfo();
}
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 113
The class extends an abstract superclass having the suffix of "_Gen". Continuing the example of an entity named
"person", the implementation class would extend a not-yet-created abstract superclass named "some.package.Person_
Gen". This superclass is created by the artifact generator based on metadata about the table and contains:
Getter methods for properties including parent objects and collections
The getDTO() and setDTO(...) methods that allow for properties to be changed
Access to standard framework methods like createQuery(...)
Business methods. Any hand coded public methods are automatically exported onto the generated business interface
(e.g. "some.package.Person"). Client code can then access the added business method as follows:
Constants. Any hand coded public static final variables are automatically exported onto the generated business interface.
This will be useful for constants related to the entity.
Having created a new entity, it is likely that validation rules and other behaviors should be added to it. Please see Adding
Change Handlers for more information.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 114
Make sure to run the artifact generator and rebuild source code after adding a Change Handler or modifying its
annotation.
//fail
countryDto.setAddress1Available(Bool.TRUE);
countryDto.setLanguageAddress1("");
try {
country.setDTO(countryDto);
fail("A validation error should have been thrown");
} catch (ApplicationException e) {
verifyViolatedRule(Country_Chandler
.addressOneLabelRequiredIfAddressOneIsAvailable(), e);
}
}
Add other test methods to test "handle" methods on the change handler as well as business methods that may have been
added.
Validation Rules
Validation rules are the mechanism for describing to the runtime system how it should validate business entities. There are a
few important characteristics of these rules:
The coding style is declarative. That is, every attempt has been made so the programmer specifies what makes data
valid, not how or when the validation should take place.
Only in the case of "custom rules" does the programmer need to build the step-by-step logic specifying how the
validation should take place.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 115
Validation rules are side-effect free. That is, they cannot change the persistent state of the system. This insures that all
the validations are performed on the complete set of changes. Likewise, it allows for the startChange()/saveChanges()
logic to safely defer the firing of rules until the end of the coherent set of changes.
The Rules
A number of useful rules are provided in the interest that the application programmer can use them with a minimum of
programming. These are classes that implement ValidationRule and can be used by application logic:
ProtectRule will protect one or more properties on an entity.
RequireRule will require that a property be populated.
AllowRule allows a value to be populated.
AllowAndRequireRule both allows and requires that a property be populated.
DecimalRule provides some common validations against decimal data types.
CustomRule will create a rule out of a CustomValidation class implementing logic that just cannot be handled by
existing rules.
RestrictRule will restrict a property to a set of values
Each of the rules above provides standard rules that represent similarly configured rules that are used repeatedly in the
system. These standard rules can be created via static "factory" methods on the rules themselves. Consider the following
standard rule:
/**
* Protect the dependant property when the primary property is equal to the supplied lookup
value.
*
* @param ruleId a unique ruleId
* @param description a description
* @param primaryProperty the property that the condition depends on
* @param dependantProperty the property that is protected when the condition is true
* @param primaryLookupValue a {@link Lookup} value that the primary property must equal for
the dependant property
* to be protected
* @return a new rule
*/
public static ProtectRule
dependantPropertyWhenPrimaryMathesLookup
(String ruleId,
String description,
SingleValueProperty primaryProperty,
SingleValueProperty dependantProperty,
Lookup primaryLookupValue)
What this rule does is prevent one property from being changed (the "dependant" property) when another property (the
"primary" property) matches a certain value. An example would be the "freeze date/time cannot be changed when the status
is 'frozen'". In this case, the dependant property would be the freeze date/time and the primary property would be the status.
The lookup value of "frozen" would be passed in as the lookup value.
Custom Rules
There are situations when custom rules need to be coded. These are for situations too complex for a declarative rule. The
process is as follows:
Create a class that extends AbstractCustomValidation. Implement one or more of the abstract methods corresponding to
various "events" that may occur with respect to the underlying entity.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 116
Within any change handler requiring this rule, instantiate a CustomRule passing in the class created above.
For details on the "events" that can be processed by the custom validation, please refer to the JavaDocs.
When coding a CustomValidation that will be used by a CustomRule. It is important to understand when these events
fire.
Eager Validations fire "immediately" when the underlying entity is changed (either via delete, setDTO(), or
createEntity()).
validateAdd() fires only on an add
validateChange() fires only when an existing entity is changed
validateAddOrChange fires in addition to either validateAdd() or validateChange()
validateDelete fires when the entity is being deleted
validateRegisteredChange() fires when "some other object is changed" (like a child). This can be any random entity
instance that feels like notifying you regarding a change of state or, more commonly, the framework automatically
registers a change when a child collection is manipulated. Your custom code can determine if a change has been made
to a child it's interested in by calling the getChangeToList() method on the change detail passed in. You just pass in the
class of your child collection and it passes back changes, if any.
Lazy Validations fire when a "coherent set of changes" is complete.
validateSave() can be used to implement validations that needs to be performed "at the end" of some set of changes.
By default a set of changes is both started and saved within individual calls to setDTO or createBusinessEntity, etc.
However, this can be controlled programmatically by calling the startChanges() and saveChanges() methods that are
available from within all business objects (change handlers, entities, components, etc). Any type of change (add, change,
deleted, register change) will trigger validateSave().
Conditions
The rules wouldn't be very useful if all you could do was always protect or require properties. This behavior is usually based
on conditions. Rules take as input one or more Conditions (e.g. objects implementing the Condition interface). Right now,
there are several conditions that can be used:
Equals. This condition can compare properties to each other or to constants (lookup values, Strings, etc). Likewise, the
size of a collection can be compared using Equals (e.g. determine personNames' size equals 0 would mean there are no
names for a person). Finally, null values can be tested using a special constant value "Constant.NULL".
Not. This is the basic boolean operator that can change the value of other conditions.
And. This is the basic boolean operator that takes two child condtions, and return true if each of them are true. This is
evaluated "lazily" and won't even evaluate the second condition if the first is false (a performance enhancement).
Or. This is the basic boolean operator that takes two child conditions, and return true if either of them are true. This is
evaluated "lazily" and won't even evaluate the second condition if the first is true (a performance enhancement).
GreaterThan / GreaterThanOrEquals. This evaluates whether one property/constant is greater than (or greater than or
equal to) to another property/constant.
LessThan / LessThanOrEquals. This evaluates whether one property/constant is less than (or less than or equal to) to
another property/constant.
Contains. These are conditions for a collection of children- at least one element has condition x, at most 2 elements
match condition y, etc). The child condition's properties should be referenced from the point-of-view of the child row.
Each of these conditions is accessible from the corresponding property or condition. There should be no reason in normal
development to use the constructors for the conditions above. Instead, you could say, for instance
Oracle Utilities Application Framework Software Development Kit Developer's Guide 117
or
Condition isAlias
= PersonName.properties.nameType.isEqualTo(NameTypeLookup.ALIAS);
or
Condition greaterThan
= PersonName.properties.sequence.isGreaterThan(BigInteger.ZERO);
or
Condition hasOnePrimaryName
= Person.properties.names.containsAtLeastOne(isPrimaryName);
or
BO-Based MO
The com.splwg.base.api.maintenanceObject.BOBasedMaintenanceObjectCHandlerHelper can be used for
the BO-based MO Change Handler validations.
The following standard validations are provided by this helper class:
The Business Object cannot be changed
The Business Object must be for the correct MO
Status is required if the Business Object has a lifecycle
Status must be a valid lifecycle status
The following methods are provided by this helper class:
Adding log entries for entity creation and entity status change (if the MO does not already have a transition algorithm)
To use the validations, create an instance of the helper class in the MO Change Handler and get the validation rules from the
Helper, as illustrated in the following sample code.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 118
OutboundCrossReferenceMessage.properties.lookOnBusinessObject() );
...
public void handleAddOrChange ( OutboundCrossReferenceMessage
changedOutboundCrossReferenceMessage,
DataTransferObject< OutboundCrossReferenceMessage> oldDTO )
{
helper.handleAddOrChange(changedOutboundCrossReferenceMessage, oldDTO);
}
public ValidationRule[] getValidationRules()
{
return helper.getValidationRules();
}
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 119
To use the validations, create an instance of the helper class in the MO Change Handler and get the validation rules from the
Helper. First you must create a new Characteristic Entity in the Characteristic Entity Lookup for your object. This entity can
be selected on any Characteristic Type to indicate that that characteristic type can be used in the log messages for this log.
Sample code follows.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 120
Standard MO Log Parameter Table
The com.splwg.base.api.maintenanceObject.MaintenanceLogParameterCHandlerHelper can be used for the
Standard MO Log Parameter Table Change Handler.
The following standard methods on Add are provided by this helper class:
Parameter sequence to next highest number
To use the Helper, create an instance of the helper class in the MO Change Handler and get the validation rules from the
Helper, as illustrated in the following sample code.
Additional Validations
Oracle Utilities Application Framework Software Development Kit Developer's Guide 121
return helper.getValidationRules(<Array of Validation Rules>);
}
/**
* Component used to query for {@link Person} instances based on various
* predefined criteria.
*
* @BusinessComponent
* (customizationReplaceable = false)
*/
public class PersonFinders_Impl
extends GenericBusinessComponent
implements PersonFinders
/**
* @param nameType a name type
* @return count of names by name type
*
* @BusinessMethod (customizationCallable = true)
*/
public int findCountByNameType(Lookup nameType) {
Query query = createQuery
("FROM PersonName name where name.nameType = :type");
query.bindLookup("type", nameType);
This example shows a "finder" component that is responsible for holding queries related to the "person" entity. These
queries are not related to any particular person because, in that case, they would rightfully belong on the entity
implementation class itself. Our (cooked up) example shows a single method that returns a count of PersonName instances
by name type.
Let's look at various parts of the component:
@BusinessComponent class annotation.
customizationReplaceable attribute specifies whether or not customers can replace this component at runtime. The
default is false. If a component is "replaceable", its methods are assumed to be "customizationCallable".
GenericBusinessComponent is extended which gives this class access to framework methods.
PersonFinders is implemented. This is the name of the generated business interface. Any customized replacement of the
business component would implement this interface as well.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 122
The business method findCountByNameType. For the method to be exported to the business interface (and therefore
callable by other business objects), it must be public.
@BusinessMethod is an optional method-level annotation.
customizationCallable specifies that this method is part of the "supported" API. That is, our customers are entitled
to call this method from their customizations and therefore, we must change this method with great reluctance in
future release.
Component Replacement
Business Components provide a simple extension mechanism where base-package code can be made available to be
replaced by customizations. For this to take place, two things must take place:
A component is added as described above with the customizationReplaceable annotation attribute set to true.
A replacement component is created that implements the business interface of the original component and also sets the
replacementComponent attribute to true.
An example, replacement of the PersonFinders component is shown below. Component implementations are registered in
the same order as the "application stack", that is "base" followed by "ccb" then followed by "cm". After the component is
defined in one application, derived applications (higher on the stack) can replace the implementation.
package com.abcutilities.cis.customizations.person;
/**
* @BusinessComponent
* (replacementComponent = true)
*/
public class CustomizedPersonFindersImpl
extends GenericBusinessComponent
implements PersonFinders {
Calling Components
Business Components are accessed via their business interfaces. Following is an example of how to call the above
component from some other business object:
Maintaining Services
This defines services available in the system. These include user interface services as well as stand-alone XAI services. Use
this transaction to introduce a new user interface or stand-alone XAI service.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 123
Note: For detailed information about service programs, please refer to user document Framework Administration,
XML Application Integration, Setting Up Your XAI Environment, Setting Up Your Registry, Service Program.
Note: For detailed information about foreign keys, see "Primary and Foreign Keys" in the Oracle Utilities Application
Framework Administration Guide.
Note: For detailed information about lookups, please refer to user document Framework Administration, Database
Tools, Defining Look Up Options.
Note: For detailed information about navigation keys, please refer to user document Framework Administration, User
Interface Tools, Defining Navigation Keys.
Note: For detailed information about navigation options, please refer to user document Framework Administration,
User Interface Tools, Defining Navigation Options.
Note: For detailed information about user interfaces, please refer to user document Framework Administration,
Configuration Tools.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 124
Maintaining Menus
This metadata represents the root of a menu "tree". A menu contains a list of menu "lines", which, in turn, contains a list of
menu "items". Lines can define navigation keys and/or associated actions, or further submenus.
Note: For detailed information about menus, please refer to user document Framework Administration, User Interface
Tools, Defining Menu Options.
Note: For detailed information on how to define application security, please refer to user document Framework
Administration, Defining Security & User Options.
Note: For information about flushing caches on the Web server, refer to the Caching Overview section in the Defining
General Options chapter of the Oracle Utilities Application Framework Administration documentation.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 125
User Language
You must log in as a user ID that has the same language as the items for which you want to modify the description. For
example, if you want to modify a French message, you must log in with a user ID that is set to use French. The instructions
in the following sections assume that you are logged in with a user ID that has the appropriate language set.
Dialog Title
To modify a dialog title:
Navigate to and open the dialog with the title that you want to change.
Right-click near the top of the dialog and select View Source from the pop-up menu.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 126
View Dialog Source
Note: Many dialogs and windows have multiple source files; so if you can't locate the field you are looking for, try
right clicking in a different area (closer to the label you want to modify). For example, if you right-click in the grid area
of the Person Search illustrated above, you will open a different source file. If you already know the name of the field
you want to modify, you can skip this step.
In the displayed source file, locate the field name that has the value you want to modify. The field for the dialog title is
clearly labelled and the current value of the field is displayed after the hyphen.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 127
Title Field Name
To modify the field override via the application, navigate to Admin Menu - Database - Field in the Oracle Utilities
Application Framework application.
When the field search dialog appears, enter the name of the field as it appears in the source.
Enter an Override Label with a title description to suit your needs and save your changes.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 128
Database - Field
Flush the server and browser caches and verify that the new dialog title appears correctly.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 129
Navigate to the transaction that has the title and/or tab name you want to modify.
Right-click in the empty area to the right or left of the tab bar and select View Source from the drop-down menu.
Note: Many dialogs and windows have multiple source files; so if you can't locate the field you are looking for, try
right-clicking in a different area (closer to the label you want to modify). To view the source for the transaction title
and tab bar, right-click directly to the right or left of the tab bar. If you already know the name of the field you want to
modify, you can skip this step.
In the displayed source file, locate the field name that has the value you want to modify. The fields for the transaction
titles and tab labels are clearly labelled and the current values of the fields are displayed after the hyphens.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 130
Transaction Title and Tab Field Names
Note: Subsystem Name. If you modify the subsystem field description, your changes will appear on every transaction
that is part of the subsystem.
To modify the field override via the application, navigate to Admin Menu - Database - Field in the Oracle Utilities
Application Framework application.
When the field search dialog appears, enter the name of the field as it appears in the source.
Enter an Override Label with a title or tab description to suit your needs and save your changes.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 131
Database - Field
Flush the server and browser caches and verify that the new field label appears correctly.
Field Labels
Field labels may be reused! A field label may be reused on multiple transactions and tabs. If you override the field's
label, your changes affect all pages and transactions on which that field label appears.
To modify the field labels that appear on transactions:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 132
Navigate to the transaction that has the field name you want to modify.
Right-click in an empty area near the label and select View Source from the drop-down menu.
Note: Many dialogs and windows have multiple source files; so if you can't locate the field you are looking for, try
right-clicking in a different area (closer to the label you want to modify). If you already know the name of the field you
want to modify, you can skip this step.
In the displayed source file, locate the field name that has the value you want to modify. The fields for the labels are
clearly identified and the current values of the fields are displayed after the hyphens.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 133
Field Label Names and Values
Note: Table-specific Fields. Note that some labels may be specific to the table on which they appear, while other
labels are generic throughout the application. If a field label is specific to a table, the table name appears before the $ in
the field list.
If the label is table-specific, navigate to Admin Menu - Database - Table in the Oracle Utilities Application Framework
application and search for the name of the table.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 134
Table Field
Enter an Override Label to suit your needs and save your changes.
If the label is not table-specific, navigate to Admin Menu - Database - Field and search for the field name.
When the field appears, enter an Override Label to suit your needs and save your changes.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 135
Database - Field
Flush the server and browser caches and verify that the new field label appears correctly.
Button Labels
To modify button labels:
Navigate to the transaction that has the button label you want to modify.
Right-click in an empty area near the label and select View Source from the drop-down menu.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 136
View Page Source
Note: Many dialogs and windows have multiple source files; so if you can't locate the field you are looking for, try
right clicking in a different area (closer to the label you want to modify). If you already know the name of the field you
want to modify, you can skip this step.
In the displayed source file, locate the field name that has the value you want to modify. The fields for the labels are
clearly identified and the current values of the fields are displayed after the hyphens.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 137
Field Label Names and Values
Navigate to Admin Menu - Database - Field in the Oracle Utilities Application Framework application and search for
the field name.
When the field appears, enter an Override Label to suit your needs and save your changes.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 138
Database - Field
Flush the server and browser caches and verify that the new field label appears correctly.
Modifying Messages
You can modify the message text and description for messages, such as error, warning and validation messages. The
following example shows a validation message:
Message
To edit messages, you need to know the message category and number. The category is the part of the message number that
appears before the comma. In the example message above, the category is 3. The number is the part of the message number
that appears after the comma. In the example message above, the message number is 253.
To edit the message text or description:
Navigate to Admin Menu - System - Message.
Specify the message category in the search dialog.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 139
Specify the starting message number and click the search icon.
System - Message
Click the go to button for the message you want to edit. You are transferred to the Details tab for that message.
Message Details
Enter the customer specific message text and description as appropriate for your needs.
Note: Message Variables. Messages may have one or more variables. Variables are indicated by a percent sign
(%) followed by a number. A value is substituted for the variable before the message is displayed. Do not modify the
message variables and make sure that your custom message contains the same number of variables as the original.
Note: For more information about system messages, please refer to user document Framework Administration, User
Interface Tools, Defining System Messages.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 140
Plugging in Algorithms
The following will illustrate the steps to create a new plug-in algorithm. This example will create a new Adhoc
characteristic validation algorithm that is very similar to a delivered plug-in.
Note: The various "Adhoc characteristic value validation" algorithms that come with the Oracle Utilities Software
Development Kit are good references for algorithm plug-ins.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 141
Parameters:
Sequence: 1, Parameter: From Date, Required: Not Checked
Sequence: 2, Parameter: To Date, Required: Not Checked
Sequence: 3, Parameter: Date Format1 (Stored Format), Required: Checked
Sequence: 4, Parameter: Date Format2, Required: Not Checked
Sequence: 5, Parameter: Date Format3, Required: Not Checked
Sequence: 6, Parameter: Date Format4, Required: Not Checked
Sequence: 7, Parameter: Date Format5, Required: Not Checked
Sequence: 8, Parameter: Age From, Required: Not Checked
Sequence: 9, Parameter: Age To, Required: Not Checked
Algorithm Type
Add Algorithm
Add a new algorithm as follows:
Algorithm: CM EXPDT-iii.
Description: Date must be a future date
Algorithm Type: CM ADHV-iiiJ
Oracle Utilities Application Framework Software Development Kit Developer's Guide 142
Effective Date: 1/1/2005
Parameters:
Sequence: 1, Parameter: blank
Sequence: 2, Parameter: blank
Sequence: 3, Parameter: YYYY-MM-DD
Sequence: 4, Parameter: YYYY/MM/DD
Sequence: 5, Parameter: MM-DD-YYYY
Sequence: 6, Parameter: MM/DD/YYYY
Sequence: 7, Parameter: MM.DD.YYYY
Sequence: 8, Parameter: 0.001
Sequence: 9, Parameter: 0
Example Zone
This section describes how to create and implement your own custom zones and use them on the existing portals provided
by the application.
Note: Required Background. As a zone developer you should have some familiarity with HTML. Further,
experience with Extensible Markup Language (XML) and XML Stylesheet Language Transform (XSLT) is very
useful, because XSLT technology provides the easiest way to render information returned from service calls.
Note: For more information on this topic, please refer to user documents Framework Administration, User Interface
Tools, The Big Picture of Portals and Zones and Setting Up Portals and Zones.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 143
Implementing Custom Zones
Portal zones are implemented as pieces of a single portal HTML page. The portal framework wraps each zone inside a div
element, and provides a title bar and collapse/expand widgets. Note that zones are not implemented as independent iframes
(though the internals of a zone could be).
Zones can be configured to be initially collapsed when the portal page loads, and then execute a deferred load when they are
expanded. This imposes some technical limitations that are discussed below.
While most zones do not depend on anything other than the current global context keys, some dashboard zones are context-
sensitive, meaning they depend on the keys of the current object being displayed.
There are two components that define a portal zone:
Metadata to define the zone and its parameters
A Java handler class
Key Dependence
Zones usually depend on one or more of the global context keys. These keys are derived from the global context lookup.
These are lookup values that each application defines for itself. When the web app server boots, the application will
enumerate the available lookup values and make this information available to the browser. For e.g. Oracle Utilities
Customer Care and Billing has ACCT_ID, PER_ID and PREM_ID as its global context keys.
In addition, context-sensitive zones can depend on model keys. For performance reasons, zones are reloaded intelligently as
needed. Hence, non-context dashboard zones generally redisplay only when one of the context keys changes.
Zone Types
A content zone is associated with a Java class (actually the interface com.splwg.base.web.portal.IPortalZoneHandler)
that is responsible for creating the zone's HTML. When a portal needs to be rendered, the server instantiates a new
handler instance for every zone for the request. In principle the handler could do anything within the bounds of the J2EE
architecture to create its content. In practice, the vast majority of zones need to make a service call and create HTML
from the result. Fortunately the SimpleZoneHandler has been designed to make this easy, and uses XSLT to perform the
transformation from the result data (as an XML document) into HTML. You will usually not need to implement your own
handler classes.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 144
Zone Type Interfaces
The interface for the IPortalZoneHandler is illustrated below:
package com.splwg.base.web.portal;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
package com.splwg.base.web.portal;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
HttpServletRequest getRequest();
ServletContext getServletContext();
String getLanguage();
boolean isLanguageLTR();
String getSequenceId();
String getName();
Oracle Utilities Application Framework Software Development Kit Developer's Guide 145
Executes XSLT transform on the result
Can display errors
Is performance optimized with stylesheet caching
In a development environment you may want to flush the stylesheet cache. Simply invoke the flushPortalMetaInfo.jsp to
clear it.
The following table describes the ServiceZoneHandler parameters:
Parameter Description
SERVICE The page service to retrieve data, e.g. CILFAFHP
XSLURL Path to XSLT file (for example, WEB-INF/xsl/linkValueGrid.xsl)
Your files should be under /cm/xsl.
ALLOW_GET_ALL Allow display of "Get All" button if the data that you want to show won't
fit in one buffer.
KEY1 - KEY5 Defines required keys. If one of these keys is empty the zone is not
rendered (unless null keys are allowed, see below).
ALLOW_NULL_KEYS If ALLOW_NULL_KEYS is "Y", only one of the keys is required (any will
work).
The following diagram illustrates example parameters for the service zone type:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 146
Zone Metadata
Debugging
There are several debugging facilities that help make portal zone development easier.
First, you should get the service working properly before worrying about the zone's HTML. For e.g you can invoke the
service through a browser and see the result (as localized XML) using this URL from a browser already logged-in to the
Oracle Utilities Customer Care and Billing system:
http://<server>:<port>/portal?type=raw&service=CILFAFHP&ACCT_ID=5922116763&PER_ID=...
Note the required parameters are the service and the keys. Don't put quotes around string arguments.
The example below shows the output of the CILCALZP service (http://<server>:<port>/portal?
type=raw&service=CILCALZP&ACCT_ID=5922116763):
Oracle Utilities Application Framework Software Development Kit Developer's Guide 147
<listBody>
<field type="string" name="KEY_NAME">ACCT_ID</field>
<field type="string" name="KEY_VALUE">5922116763</field>
</listBody>
</list>
</listBody>
<listBody>
<field type="string" name="FIELD_LABEL"></field>
<field type="string" name="FIELD_VALUE">Account used in Billing test Plan</field>
<field type="string" name="TOOLTIP_LBL_FIELD">GO_TO_ACCOUN_LBL</field>
<field type="boolean" name="CHILD_ROW">false</field>
<field type="string" name="SORT_KEY">ACCALT</field>
<field type="string" name="NAVIGATION_KEY">accountMaint:9</field>
<field type="string" name="MENU_NAME"></field>
<list name="KEY">
<listHeader/>
<listBody>
<field type="string" name="KEY_NAME">ACCT_ID</field>
<field type="string" name="KEY_VALUE">5922116763</field>
</listBody>
</list>
</listBody>
<listBody>
<field type="string" name="FIELD_LABEL"></field>
<field type="string" name="FIELD_VALUE">Cable Customer</field>
<field type="string" name="TOOLTIP_LBL_FIELD">GO_TO_SERVIC_LBL</field>
<field type="boolean" name="CHILD_ROW">false</field>
<field type="string" name="SORT_KEY">SATYPE</field>
<field type="string" name="NAVIGATION_KEY">saMaint</field>
<field type="string" name="MENU_NAME"></field>
<list name="KEY">
<listHeader/>
<listBody>
<field type="string" name="KEY_NAME">ACCT_ID</field>
<field type="string" name="KEY_VALUE">5922116763</field>
</listBody>
</list>
</listBody>
...
</list>
</pageBody>
Alerts Zone
Oracle Utilities Application Framework Software Development Kit Developer's Guide 148
Field Role
FIELD_VALUE Supplies displayed text.
NAVIGATION_KEY Provides navigation option.
KEY List of up to six context keys.
CHILD_ROW Boolean that forces a slight left-indent.
The LabelValueGrid is similar, but it uses MENU_NAME to define the desired context menu.
(Reuse directly).
<?xml version="1.0"?>
<page service="CILCALZP">
<pageHeader>
<boolean name="PAGE_READ_SW"/>
<string name="ACCT_ID" size="10"/>
<string name="PER_ID" size="10"/>
<string name="PREM_ID" size="10"/>
<string name="LAST_KEY_COMBINATION" size="100"/>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 149
</pageHeader>
<pageBody>
<list name="ZONE" size="60">
<listHeader lastIndex="ZONE_COLL_CNT"></listHeader>
<listBody>
<string name="FIELD_LABEL" size="50"/>
<string name="FIELD_VALUE" size="254"/>
<string name="TOOLTIP_LBL_FIELD" size="18"/>
<boolean name="CHILD_ROW"/>
<string name="SORT_KEY" size="30"/>
<string name="NAVIGATION_KEY" size="30"/>
<string name="MENU_NAME" size="30"/>
<list name="KEY" size="6">
<listHeader lastIndex="KEY_COLL_CNT"></listHeader>
<listBody>
<string name="KEY_NAME" size="18"/>
<string name="KEY_VALUE" size="30"/>
</listBody>
<list>
</listBody>
</list>
</pageBody
</page>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 150
<xsl:with-param name="key" select="'$ARS_DT'" />
</xsl:call-template>
<xsl:call-template name="labelCell">
<xsl:with-param name="key" select="'$FT_TYPE_FLG'" />
</xsl:call-template>
<xsl:call-template name="numberLabelCell">
<xsl:with-param name="key" select="'CI_FT$CUR_AMT'" />
</xsl:call-template>
<xsl:call-template name="numberLabelCell">
<xsl:with-param name="key" select="'$CURRENT_BALAN_WRK'" />
</xsl:call-template>
<xsl:call-template name="numberLabelCell">
<xsl:with-param name="key" select="'CI_FT$TOT_AMT'" />
</xsl:call-template>
<xsl:call-template name="numberLabelCell">
<xsl:with-param name="key" select="'$DERIVED_AMT_WRK'" />
</xsl:call-template>
</tr>
<xsl:apply-templates select="$list" />
</table>
</xsl:if>
</xsl:template>
<xsl:template match="listBody">
<xsl:variable name="financialTransactionType">
<xsl:value-of select="field[@name='FT_TYPE_FLG']" />
</xsl:variable>
<xsl:variable name="payEventId">
<xsl:value-of select="field[@name='PAY_EVENT_ID']" />
</xsl:variable>
<xsl:variable name="parentId">
<xsl:value-of select="field[@name='PARENT_ID']" />
</xsl:variable>
<xsl:variable name="siblingId">
<xsl:value-of select="field[@name='SIBLING_ID']" />
</xsl:variable>
<tr>
<xsl:attribute name="position">
<xsl:value-of select="position()" />
</xsl:attribute>
<xsl:call-template name="rowClass" />
<td class="gridTd" width="1">
<img src="/images/goto_sm.gif" xsl:use-attribute-sets="imageButton"
onclick="handleAccountFinancialHistoryContext('{$financialTransactionType}',
'{$payEventId}', '{$parentId}', '{$siblingId}')" />
</td>
<xsl:variable name="currentAmount" select="field[@name='CUR_AMT']" />
<xsl:variable name="currentBalance" select="field[@name='CUR_BAL']" />
<xsl:variable name="payoffAmount" select="field[@name='TOT_AMT']" />
<xsl:variable name="payoffBalance" select="field[@name='TOT_BAL']" />
<xsl:call-template name="dateCell">
<xsl:with-param name="value" select="field[@name='ARS_DT']" />
</xsl:call-template>
<xsl:call-template name="valueCell">
<xsl:with-param name="value" select="field[@name='DESCR']" />
</xsl:call-template>
<xsl:call-template name="numberCell">
<xsl:with-param name="value" select="$currentAmount" />
</xsl:call-template>
<xsl:call-template name="numberCell">
<xsl:with-param name="value" select="$currentBalance" />
</xsl:call-template>
<xsl:call-template name="numberCell">
<xsl:with-param name="value" select="$payoffAmount" />
<xsl:with-param name="dimmed" select="$currentAmount = $payoffAmount" />
</xsl:call-template>
<xsl:call-template name="numberCell">
<xsl:with-param name="value" select="$payoffBalance" />
<xsl:with-param name="dimmed" select="$currentBalance = $payoffBalance" />
Oracle Utilities Application Framework Software Development Kit Developer's Guide 151
</xsl:call-template>
</tr>
<script type="text/javascript" defer="defer">
function handleAccountFinancialHistoryContext(financialTransactionType,
payEventId, parentId, siblingId) {
switch (financialTransactionType) {
case 'PS' :
case 'PX' : {
handleGotoContext('paymentEventMaint', 'PAY_EVENT_ID', payEventId);
break;
}
case 'BS' :
case 'BX' : {
handleGotoContext('billMaint', 'BILL_ID', parentId);
break;
}
case 'AD' :
case 'AX' : {
handleGotoContext('adjustmentMaint', 'ADJ_ID', siblingId);
break;
}
}
}
</script>
</xsl:template>
</xsl:stylesheet>
XML Metainfo
The following excerpt shows the XML Meta Info for the Account Financial History.
<?xml version="1.0"?>
<page service="CILFAFHP">
<pageHeader>
<boolean name="PAGE_READ_SW"/>
<string name="ACCT_ID" size="10"/>
<boolean name="LIMITED_SW"/>
</pageHeader>
<pageBody>
<string name="ENTITY_NAME" size="64"/>
<string name="ACCT_ID" size="10"/>
<list name="ACCT_FT_HIST" size="25" service="CILFAFHL">
<listHeader/>
<string name="ACCT_ID" size="10"/>
<boolean name="LIMITED_SW"/>
<string name="LAST_PARENT_ID" size="14"/>
<date name="LAST_ARS_DT"/>
<string name="LAST_CURRENCY_CD" size="3"/>
<string name="LAST_FT_TYPE_FLG" size="2"/>
<money name="LAST_CUR_AMT" precision="15" scale="2"/>
<money name="LAST_TOT_AMT" precision="15" scale="2"/>
<money name="LAST_CUR_BAL" precision="15" scale="2"/>
<money name="LAST_TOT_BAL" precision="15" scale="2"/>
</listHeader>
<listBody>
<string name="ACCT_ID" size="10"/>
<date name="ARS_DT"/>
<string name="PARENT_ID" size="14"/>
<string name="PAY_EVENT_ID" size="12"/>
<string name="SIBLING_ID" size="12"/>
<string name="FT_TYPE_FLG" size="2"/>
<string name="DESCR" size="50"/>
<money name="CUR_AMT" precision="15" scale="2"/>
<money name="TOT_AMT" precision="15" scale="2"/>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 152
<money name="CUR_BAL" precision="15" scale="2"/>
<money name="TOT_BAL" precision="15" scale="2"/>
<currency tuxedo="CURRENCY_CD"/>
</listBody>
</list>
</pageBody>
</page>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 153
XSLT Debugging
There are some techniques to help debug your XSLT files. Malformed XSLT will cause error messages to appear in the
WebLogic console. In addition, you can test the layout of a portal zone in isolation using this URL from a browser that is
logged-in to the Oracle Utilities Customer Care and Billing system:
http:<server>:<port>/portal?type=xslTest&service=CILCALZP&xslURL=/WEB-INF/xsl/linkValueGrid.xsl&ACCT_
ID=5922116763
(Ignore any JavaScript errors)
The important parameters are the service, the xslURL, and the service keys.
HTML Standards
Since portal zones are simply div elements within a single HTML page, they must co-exist harmoniously (for example,
don't assume HTML IDs are unique).
Here are some tips to avoid problems:
Avoid hard-coding sizes (e.g. widths). It's best to let the browser manage the resizing of zones when the browser window is
resized by the user. One tip: Use width 100% for tables and divs.
There is an IE Bug with JavaScript in documents loaded after the main page has loaded, so-called deferred loading. To
support deferred loading, JavaScript tags must use the defer attribute:
Further, such JavaScript code should appear at the bottom of the zone. Refer to the existing XSLT files for examples.
Rely on the standard Oracle Utilities Customer Care and Billing cascading style sheets (cisDisabled.css), which are
automatically loaded in the portal page. Some useful style classes are "normal", "label", and "biggerText".
Since an HTML page provides a single global namespace for widget IDs, avoid hard-coding HTML IDs. If you absolutely
must, you may want to make use of the sequenceId XSLT template variable, which provides a unique ID to every zone
when it renders.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 154
the framework. The framework then makes calls to the BatchJob instance at the appropriate time. One such set of calls
to the BatchJob instance is to return to the framework a collection of ThreadWork instances that will be distributed for
execution.
A ThreadWorker is responsible for processing a single ThreadWork instance for a run. Within the ThreadWork there are
many WorkUnits representing the fine-grained units of work to be processed. In many cases the WorkUnits represent
a complete database transaction, for example, a bill being created for an account. Whether or not the ThreadWorker
executes on the same computer as other ThreadWorkers or the BatchJob that created its work is left as a configuration
choice to be made at runtime. Within a single process, there may be many ThreadWorker objects. In general, each
ThreadWorker instantiated in a batch run has a corresponding row in the Batch Instance table. The Batch Instance rows
provide persistent state that is needed for the ThreadWorkers to operate correctly in failure/restart situations.
Creating a BatchJob
A BatchJob class is responsible for determining what work needs to be done within the run and splitting the work among
ThreadWorkers.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 155
The annotation declares if the job can be rerun, supports more than one thread of operation, the modules that the job belongs
to, its nonstandard runtime parameters and the details of how "ToDo" entries should be created in the case of errors. When
not specified in the annotation, default values will be used.
Creating JobWork
The most important goal of a BatchJob class is to return an instance of JobWork describing what work should be done
(ThreadWorkUnits) and have that work split into manageable chunks (ThreadWork) that can be processed by a single
ThreadWorker.
Most commonly, ThreadWorkUnits contain only the ID values of the entities to be processed. For example, one can
envision a process that performs an operation on a set of accounts. In general, one would expect that each ThreadWorkUnit
would contain a single AccountId. The ThreadWorker objects would then be constructed in such a way that when asked to
execute for a ThreadWorkUnit it would pull out the embedded AccountId and then perform the required business function.
There are convenience methods available from the AbstractBatchJob that make it easier to create JobWork instances. For
example, the createJobWorkForEntityQuery(Query) method will accept a query returning BusinessEntity instances and
create a JobWork instance containing the appropriate number of ThreadWork instances each containing (notwithstanding
rounding) the same number of ThreadWorkUnits.
Creating a ThreadWorker
The ThreadWorker performs the "heavy lifting" of a batch process. For a given run, there will ThreadWorkers created equal
in number to the "thread count" parameter provided when a process is requested.
Initializing ThreadWork
Each ThreadWorker instance can expect to have its initializeThreadWork() method called once by the framework before
any actual work is to be performed. This method may be implemented to do any setup necessary for that thread's execution,
most commonly output files opened or variables initialized.
It is very important that any setup necessary to execute a WorkUnit is done here and not in the creation of JobWork,
this includes accessing batch parameters. There is no guarantee that static variables set at the time of JobWork creation
will be available at this time. The framework may be calling ThreadWork in a different process from the creation of
JobWork.
Executing a WorkUnit
The ThreadWorker can expect that its executeWorkUnit method will be called once for each ThreadWorkUnit that that
ThreadWorker will process. For example, if the batch process will act upon 10,000 accounts and the process is submitted
with a ThreadCount=10, we can expect that there are 10 ThreadWorkers created by the framework and each worker will
have its executeWorkUnit method called by the framework for each of the 1,000 ThreadWorkUnits allocated to that thread.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 156
Finalizing ThreadWork
Each ThreadWorker instance can expect to have its finalizeThreadWork() method called once after all ThreadWorkUnits
have been processed. This gives the opportunity to close any open files or to do any other "tear down" processing for the
ThreadWorker.
Choosing a ThreadExecutionStrategy
ThreadWork instances need to provide a strategy defining the execution policies for its work. That is, how the work for a
thread will be processed. The interface that is implemented is ThreadExecutionStrategy. The most important aspect of this is
how exceptions will be treated with respect to transactions.
Should all the ThreadWorkUnits be wrapped in a single transaction with a single rollback on an exception?
Should each ThreadWorkUnit be in its own transaction?
Should the framework attempt to process many ThreadWorkUnits within a single transaction?
If an exception occurs should the framework "back up" and reprocess the successful units?
In general, new background processes are expected to chose from existing instances of ThreadExecutionStrategy, not
create new ones. Please scan for existing implementations of ThreadExecutionStrategy.
Creating MO XMLs
Run batch process F1AVGMO.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 157
Creating Javadocs for CM Source Code
Javadocs can be created for CM source code. They are designed to be integrated into the product's Javadocs that are
delivered in the Application Viewer.
The product's Javadocs are only delivered for objects or supporting objects that are intended to be referenced by CM code.
For instance, only the domain and api packages are included, and some of the files created by the artifact generator are not
delivered since they have no practical relevance to CM code. These files have been deliberately and explicitly omitted when
creating the product's Javadocs.
Note that the process that generates Javadocs on CM source code is not selective, and running Javadocs on CM source code
may include more object types than what is delivered with the product's Javadocs.
There is one location that is used for both the product and CM Javadocs. Because they share the same location, there are
two steps involved in creating CM Javadocs.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 158
JSP name Main purpose XSLT name Main purpose
setNavKeyIndex Sets the desired navKeyIndex overrideNavKeyIndex Returns the desired index of the
variable. nav key.
setImageOpenIndex Sets the desired imageIndex overrideImageOpenIndex Returns the desired index of the
variable. open image.
setImageClosedIndex Sets the desired imageIndex overrideImageClosedIndex Returns the desired index of the
variable. closed index.
Each user exit is passed the variable's original value. If the user exit does not return a value, the original variable's value will
be used.
Below is an example of a JSP user exit and a converted XSLT user exit inside an .xjs file.
Here is the JSP user exit.
// $#BSES SETSERVICE
if (nodeName == 'newtype') {
var myLetter = pageKeys.FT_TYPE.substr(0,1);
if (myLetter == 'A') {
serviceIndex = 1;
}
if (myLetter == 'B') {
serviceIndex = 2;
}
if (myLetter == 'C') {
serviceIndex = 3;
}
if (myLetter == 'P') {
serviceIndex = 4;
}
}
// $#BSEE SETSERVICE
Oracle Utilities Application Framework Software Development Kit Developer's Guide 159
Run the SQLs in the script changeTemplateCodesTTRAndPN.sql against your database to perform this change.
Utilities
displayEnvironment.bat
Property Detail
Purpose Displays the current configuration.
Description Displays a set of environment variables and settings that may be
needed to diagnose compile issues.
Usage displayEnvironment.bat
Parameters None.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 160
switchEnvironments.bat
Property Detail
Purpose Sets the current development environment (project) for the Software
Development Kit.
Description Displays a list of development environments on the development client,
allows the user to select one, and sets it as the current development
environment for the Software Development Kit.
Usage switchEnvironments.bat
Parameters None.
createNewEnv.bat
Property Detail
Purpose Creates a new development environment (project) or configures
a development environment to use the version of the Software
Development Kit used for the current development environment.
Description Configures a new app server to be a development environment.
Also, executing this for an existing development environment configures
that development environment to use the version of the Software
Development Kit used by the current development environment.
Usage createNewEnv.bat -a <appServerDir>
Parameters
-a <appServerDir>. Specify the base directory of the app server to
configure.
Services
Oracle Utilities Application Framework Software Development Kit Developer's Guide 161
Property Detail
Description Updates the XML Metainfo directory of the current development
environment with the latest service XMLs. This is needed, for example,
for creating schemas for XAI.
Usage updateXMLMetainfo.bat
Parameters None.
Eclipse Tools/Wizards
There are a few wizards and tools available for developing against the framework within Eclipse plugins.
Annotation Editor
A lot of the Java classes that will be created to add behavior to the application require Annotations to provide meta-data
about the implementation (see Java Annotations chapter in the Developer Guides).
The annotation editor plugin provides a convenient way to edit the annotations on these classes. It is available on any class
that has an existing annotation, under the Package Explorer panel in Eclipse. Right click on the file in the Package Explorer,
and there will be a menu item "Edit Annotation".
Oracle Utilities Application Framework Software Development Kit Developer's Guide 162
Choosing this menu item will cause a new dialog window to appear, and the file to open into an editor if it is not already
open. The dialog that appears will allow maintenance of the file's current annotation contents.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 163
The appearance of the dialog is dependent upon the particular annotation, but the standard dialog will present a layout of
two columns, a label and an input for each annotation property. The bottom of the dialog will always present the Finish and
Cancel buttons. The Cancel button is always available, and will throw away any changes made, leaving the file with the
annotation unchanged.
The Finish button will only be enabled when the annotation has no errors. The annotation is validated after any change, and
errors will be displayed near the top of the dialog and the Finish button disabled.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 164
When the property value is itself a list of values or another annotation, there will a button instead of an input text box.
Clicking the button will bring up another dialog to edit its information. In the case of lists, there is a standard dialog where
elements can be added, deleted, or reordered.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 165
To add a new element, click the '+' button. This will popup a new dialog for the annotation being added (or sometimes a
choice of the new annotation's type might need to be chosen first). Clicking the '-' button will delete the highlighted element.
The 'up' and 'down' buttons can be used to move the highlighted element up or down within the list. To modify an existing
element, double click its row in the list dialog, and a new dialog will open to edit its values.
Finally, there is a special list dialog for lists of strings. Instead of editing the elements in the list in a new dialog, a single
input field near the bottom of the dialog is used to edit the highlighted entry.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 166
When the finish button is finally pressed, the annotation (and only the annotation) in the file will change to contain the new
values entered into the annotation dialogs. The changed file's annotation may be slightly reformatted. The changed file will
also remain unsaved, pending user review of the annotation's changes.
<buildSpec>
<buildCommand>
<name>com.splwg.tools.dbConnection</name>
<arguments>
<dictionary>
<key>url</key>
<value><URL></value>
</dictionary>
<dictionary>
<key>username</key>
<value><USERNAME></value>
</dictionary>
<dictionary>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 167
<key>password</key>
<value><PASSWORD></value>
</dictionary>
</arguments>
</buildCommand>
...
</buildSpec>
The values <URL>, <USERNAME>, <PASSWORD> should be replaced (including the surrounding '<' and '>') with the
appropriate values for the database for the project.
This file will need to be hand edited, and Eclipse should be restarted after the edit is complete.
The second way is to provide a workspace-wide database connection. This is available in an Eclipse preference- go to
"Window | Preferences...". Then in the tree pane on the left of the Preferences dialog, choose "SPL Preferences". Under
OUAF preferences, choose "Database Connection". The preference pane on the right will now show inputs for the database
connection information.
Click the override default DB connection if the database contains materialized views to the true development database for
performance reasons. Enter the information into the appropriate text boxes and click OK. This will take effect immediately,
without need of restarting Eclipse.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 168
The "Maintenance Object Wizard" is available under the "New .." menu item, either under the file menu, or by right
clicking a node in the package explorer (the package explorer option is recommended, as it will default the project and
source directory selected). From the list of new wizards available, choose "Other...".
This will open a new dialog, where the maintenance object wizard is under SPL:
(Note that you can configure Eclipse so that in the future the "Maintenance Object implementation classes" wizard appears
directly under the first "New..." menu.)
Oracle Utilities Application Framework Software Development Kit Developer's Guide 169
The first page of the wizard asks for the project and source path to place the new files. Then it asks for the some information
it uses to construct the package name for the new files. The standard is that the new classes go under the application's
domain path, with a possible extra sub package (e.g., a subsystem, like 'common' or 'customerInformation'), followed by the
top level entity's name (e.g., account). The top level entity's name, along with lots of data used by the next page, comes from
the maintenance object itself.
Finally, you can optionally choose to Generate the UI Maintenance (the default is to generate it).
The maintenance object input has a "Browse..." button associated with it that will launch a search dialog where the
maintenance object can be searched for by either the Maintenance Object's code, or by the primary table for the
maintenance object.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 170
Both of these searches are "likable" in that partial matches starting with the input will be shown.
Pressing OK on the search or double clicking a row will bring the selected maintenance object back into the Maintenance
Object input on the main wizard.
Once the main wizard's inputs are specified, the next button can be pressed. This will display the second detailed wizard
page. A tree view is displayed with the tree representation of the Maintenance object selected, with its child tables.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 171
Each node in the tree must be visited in order to enter some information or at least verify that the default data is correct. The
nodes themselves show the list property name, the table, whether the table has a language table, and whether the node has
been verified.
The selected node's data is shown in the "Info" box below the tree. Only editable information is available to be changed-
other values may be disabled. The values that can be changed for each node include the list property name, the order by
fields, the clustering parent property, and whether the Id can contain mixed case.
The list property name is the name on the parent that the child collection will be accessed by. For example, in the above
Maintenance Object for Table, the table's child collection of rows on the table CI_MD_CONST will be accessed via the
property 'constraints'. And likewise, each constraint will then have a child collection called fields.
The order by is an optional property. It is a comma-separated list of columns that specify the order in which the list will be
retrieved when the collection is read from the database. An example for the constraints collection would be "CONST_ID,
OWNER_FLG".
The clustering parent property comes into play for generated IDs. In some cases, it is beneficial to cluster the generated
keys for related objects so that batch threading is more efficient. An example is every Service Agreement can have its ID
generated with some portion of its account ID. The account will be accessed off of a serviceAgreement via the property
account. Thus the Service Agreement root node in the above dialog would probably have a value of 'account' for the
clustering parent property.
In case of user defined string keys, most of the time the application only uses uppercase keys. However, in some cases,
mixed case keys are allowed. The "Allow mixed case Id" check box should be checked in this event.
Finally, to ensure that the developer reviews each node's values, the Verified check box must be checked for each node,
prior to proceeding to the next page or finishing.
If the option to generate the Maintenance was not chosen, the Finish button will be enabled when the tree nodes' data is
complete and valid. Clicking finish will cause all of the entity classes to be created in the specified package, and will open
an editor window on each new class.
If the option to generate the Maintenance was chosen on the first page, the "Next>" button should be enabled after all the
tree nodes data is finished and valid. Clicking "Next" will then present the final wizard page, where information about the
maintenance class can be entered.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 172
On this page, the maintenance class name and maintenance type can be chosen. The maintenance class name is something
like the root entity name followed by 'Maintenance" by convention, although it can differ. The maintenance type choices
are 'Entity', which is a standard maintenance for a single instance of the maintenance object at a time, with nested child lists,
etc. The other choice is 'List", which is a simplified maintenance where many instances of the maintenance object are edited
at once in a grid. This is usually limited to simple objects with a code and description, and maybe one or two other fields.
Anything more complex would be difficult to present in the single grid.
(Note that changing the Maintenance Type will clear out any existing information on the annotation.)
After the class name and maintenance type is chosen, there is more information required to be edited on the Annotation. See
Java Annotation in the Developer Guide for details about annotations. Clicking on the "Edit Annotation" button will launch
a new dialog window for editing the annotation. The most important information that every maintenance must specify on
the annotation is the service name. This field is immediately visible on the main dialog for the annotation, and must have
a value entered. Most everything else will have been defaulted with appropriate values from the Maintenance Object meta
data. See the developer guide mentioned above for more information on using the annotation editor.
After the maintenance information and annotation is complete and valid, pressing finish will cause the entity files and an
empty maintenance class to be created, and editor windows opened on each of them.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 173
convertTreePageExits Purpose
Creates user exit files from tree JSP files.
convertTreePageExits Description
This program creates user exit .xjs files for all tree JSP files under the current and child directories. The .xjs file will be
created in the same directory with the same name as the JSP.
This should be run from a command prompt in the directory or parent directory of the JSP files.
convertTreePageExits Usage
Perl convertTreePageExits.pl
convertSubPanelExits Purpose
Creates user exit files from subpanel JSP files.
convertSubPanelExits Description
This program creates .xjs files for all subpanel JSP files under the current and child directories. The .xjs file will be created
in the same directory with the same name as the JSP.
This should be run from a command prompt in the directory or parent directory of the JSP files.
convertSubPanelExits Usage
Perl convertSubPanelExits.pl
changeTemplateCodesTTRAndPN Purpose
Changes the tree and subpanel template codes to the XSLT template codes.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 174
changeTemplateCodesTTRAndPN Description
This changes the template codes of from JSP to XSLT template codes. This template code instructs the application to use
the XSLT engine instead of the referring to a JSP.
These SQL commands should be run against the database.
Javadocs
Oracle Utilities Application Framework Software Development Kit Developer's Guide 175
Chapter 3
Developer Guide
Overview
The Oracle Utilities Application Framework provides a rich environment for developing applications. This document
provides a reference for various topics that will help developers make the most of this application development framework.
The sections in this document include:
The Java Annotations section describes the meta-data that can be embedded in Java code for various purposes.
The Public API section describes available methods, interfaces, etc., in the various Java classes like entities,
maintenance classes, etc.
The Application Logs section describes how logs are set up and used.
The Java Programming Standards section describes Java coding practices that promote efficient development and
maintenance as well as upgradeability.
The HQL Programming Standards section describes HQL coding practices that promote efficient development and
maintenance as well as upgradeability.
The SQL Programming Standards section describes SQL coding practices that promote efficient development and
maintenance as well as upgradeability.
The Database Design Standards section describes database design practices that promote an efficient database,
maintenance as well as upgradeability.
The System Table Guide section describes the set of database tables that contain crucial information for the
configuration and operation of the application. It also describes standards to be followed to ensure upgradeability.
The Key Generation section describes the automatic generation of random and sequential primary keys.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 176
Java Annotations
In order to direct the application how to deal with the code in certain classes, annotations are employed. These annotations
can direct the generator how to generate the superclass, how to register the class, and at runtime can effect the behavior of
the class. The annotations are potent metadata used at several levels in the application.
Technically, the annotations are structures described inside a JavaDoc comment prior to the start of classes or methods.
They are structured via starting with a '@' sign, followed by the annotation name, and the body of the annotation inside
parenthesis. The body can be either comma separated key=value pairs or a single value which specifies a value for a unique
default key. The values can be any of strings (needing to be bound by quotes if there are special characters inside the string
itself), lists (of either annotations or strings) bound by curly braces {} and separated by commas, or other annotations.
Each managed class (entity, change handler, business component, maintenance, etc.) typically has its own annotation. Each
of these annotations has an underlying Java class in the com.splwg.shared.annotations package, where the name of the class
is the name of the annotation suffixed by Annotation. The JavaDoc comments of these annotation classes should give more
detail for each specific annotation.
An example will help illuminate:
Here is the entity annotation for batch control:
/**
* @BusinessEntity (tableName = CI_BATCH_CTRL,
oneToManyCollections = { @Child (collectionName = parameters, childTableName = CI_
BATCH_CTRL_P,
orderByColumnNames = { "SEQ_NUM"})})
*/
public class BatchControl_Impl
The name of the annotation is BusinessEntity. It has specified properties tableName, and oneToManyCollections (there
are others available, but they need not all be specified). The property tableName specifies the CI_BATCH_CTRL table
as the table that this entity maintains. It also contains some oneToMany child collections, specified by the list of Child
annotations. In this case, there is a single child, with a collection name of parameters, pointing to the child table CI_
BATCH_CTRL_P, with a native order given by the column name SEQ_NUM.
Once an annotation exists, the annotation wizard (in the Eclipse editors plugin) can be used to maintain the annotation,
showing all of the available annotation properties, and with some validation of the values entered. Thus, one way to create
an annotation from scratch is to create a purely empty annotation with the correct name at the start of the class, and then
use the annotation editor to fill in the details, and assure against typographical errors and not have to hunt down the allowed
properties.
Here is a list of top-level annotations and their corresponding purpose or managed class type, and a pointer to an example
class in the FW code where available.
BatchJobAnnotation for batch jobs, defining such properties as whether the batch is multithreaded and what soft parameters
it uses. An example batch job in Java is defined in the class com.splwg.base.domain.todo.batch .BatchErrorToDoCreation.
BusinessComponentAnnotation for business components. This will register the business component either as a new one
(and define whether it can be replaced or not), or a replacement of an existing one. An example business component is
com.splwg.base.domain.todo.toDoEntry.ToDoEntryAssigner_Impl.
AlgorithmComponentAnnotation for defining algorithm implementations. This is used to create a new algorithm
implementation, defining which algorithm spot it is for, and what soft parameters it uses. An example algorithm component
is com.splwg.base.domain.common.characteristicType.AdhocNumericValidationAlgComp_Impl.
EntityChangeAuditorAnnotation for implementing audit behavior when an entity is modified. An example auditing
component is com.splwg.base.domain.common.audit.DefaultTableAuditor_Impl.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 177
BusinessEntityAnnotation for defining or extending business entities, with properties defining the table maintained and any
one-to-many child tables, etc. An example entity is com.splwg.base.domain.batch.batchControl.BatchControl_Impl.
ChangeHandlerAnnotation for extending entity persistence behavior- adding validations, or
adding extra code to execute on add/change/delete actions. An example change handler is
com.splwg.base.domain.common.characteristicType.CharacteristicType_CHandler.
CodeDescriptionQueryAnnotation for adding services to handle drop down lists for the UI. There are no examples of this
general component- the Oracle Utilities Application Framework implements only entity code descriptions.
EntityCodeDescriptionQueryAnnotation for adding services to handle drop down lists for the
UI, that are directly related to entities. An example of an entity code description component is
com.splwg.base.domain.common.country.CountryCodeDescriptionQuery.
MaintenanceExtensionAnnotation for extending a maintenance. There are no examples of maintenance extensions in the
framework. It is purely an implementer component. Please see Maintenance Extensions (User Guide: Cookbook: , Hooking
into User exits: Hooking into Maintenance Class User Exits).
QueryPageAnnotation for creating a new query page service. An example is
com.splwg.base.domain.todo.toDoQueryByCriteria.ToDoQueryByCriteriaMaintenance.
PageMaintenanceAnnotation for creating a new generic page maintenance. An example is
com.splwg.base.domain.security.user.SwitchUserLanguageMaintenance.
EntityListPageMaintenanceAnnotation for creating a new maintenance for an entity-type, with a list based front end. An
example is com.splwg.base.domain.common.phoneType.PhoneTypeListMaintenance.
EntityPageMaintenanceAnnotation for creating a new entity maintenance, that maintains a single instance at a time. An
example is com.splwg.base.domain.batch.batchControl.BatchControlMaintenance.
ListServiceAnnotation for creating a list service (read only), meant for trees for example. An example is
com.splwg.base.domain.security.user.UserAccessGroupCountListInquiry.
Public API
Oracle Utilities Application Framework Software Development Kit Developer's Guide 178
SQL Execution Result SPL Return Code
Deadlock 999999995
No connection 999999996
* Application Error 999999997
* Hibernate Error 999999998
* Programmatic Error 999999999
Note: The SQL return codes marked with an asterisk ("*") are for errors peripheral to the actual execution of the SQL and do not have equivalent database
return codes.
Public Methods
These methods are exposed via the generated "business interface" of the entity.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 179
registerChange(Change) - Allows for another entity to register the fact that that entity has changed so that any dependant
change handler logic in this entity may fire. This is most useful in situations where the changed object and the dependant
object (the one needing to know about the change) are not directly related by parent-child relationships.
getDTO() - Get a DataTransferObject representing the current state of the entity.
setDTO(DataTransferObject) - Update the state of the entity based on the passed values in the DTO.
getId() - Each entity has a method by this name with retrieves and Id instance of the appropriate class for the entity.
getFoo() - Get the value of the persistent property "foo".
fetchBar() - Convenience method that will fetch the value of "bar" where "bar" is a parent entity referenced by an
optional foreign key refernce. The word "fetch" is used to denote that navigation to that entity is not provided from
within HQL.
getBazzes() - Get the EntityList containing members of the entity "baz". For example, a getPersonNames() method on
the "person" entity might return an instance of an EntityList containing PersonName instances.
Protected Methods
These methods are exposed via the extended generated superclass of an entity (the "_Gen" class) for the use of business
methods implemented on the entity. With few exceptions, the methods exposed as public methods on business entities are
also exposed "within" the entity as protected methods for the convenience of business logic. Additionally, the following
methods are added:
thisEntity()-Returns the instance of the current entity. Generally, this is used when an entity needs to pass itself as an
argument in a method call.
addError(ServerMessage)-Add an error relating to the current entity.
addError(ServerMessage, Property)-Add an error relating to the passed property on the current entity.
addWarning(ServierMessage)-Add a warning to the current warning list.
Id Methods
Entities generally have an Id class created for them by the artifact generator. This provides clarity in the application code
as to what "kind" of Id is being held or passed. Likewise, there are useful methods on these Id classes. Id instances are
immutable.
getEntity()-Get the business entity that this Id refers to or null if no such entity instance exists.
getFoo()-In the case where the Id contains a persistent entity "foo", return that entity.
getBarId()-Get the contained Id referring to the entity "bar".
newDTO()-Create a new DTO instance with the Id property already set to this Id's value.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 180
Maintenance Class Public Methods
Please refer to the Javadocs for the public API.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 181
This document assumes that you are familiar with the framework architecture and its UI program component templates
(XSLT) and that you know how the base exits work. It also assumes that you are proficient in JavaScript and HTML.
Flowchart Legend
Whenever you see a request for a server-side page service, you can refer to the Page Maintenance Program flowchart to see
the server-side processing. You can determine the Page Action based on the service being requested: Read, Add, Change,
Delete, or Default.
Read Page
The Read Page function is executed whenever data needs to be presented from the database to the user. It is called after a
root item is selected from a search page or when navigating to another transaction via a Go To button or a Context menu.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 182
Delete Page
The Delete Page function is executed when the user clicks the Delete icon.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 183
Save Page
The Save Page function is called whenever a user clicks the save icon (or the associated accelerator key). If the user has
displayed an existing object on a maintenance page, the Action Flag and therefore the Change Page Service is requested. If
an existing object is not displayed on a maintenance page and the user presses save (e.g., they are adding a new object to the
database), the Action Flag does not equal change and therefore the Add Page Service is called.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 184
Refresh Page
The Refresh Page function is called from the Read, Delete, and Save page processes. It is also called when the user clicks
the Refresh Page icon (or the related accelerator key) or when the user navigates to a different tab page.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 185
The pre/post Tab Page Window Load user exit is a good place to implement Field Level Security logic. By using the
getFieldLevelSecurityInfo() function found on the "top" object (please refer to the Free Functions section found within the
Technical Background chapter of the Development Tools documentation), an implementer can extend the behavior or look
of the window. For example, a field can be made "read-only" if the user's Field Level security is lower than the required
security level. This prevents the user from changing the value of the field.
You can use pre/post List Grid Row Processing exit to manipulate fields within the grid. For example, you can calculate the
default value of a column depending on the values of other columns.
Update Field
The Update Field function is called when a user changes the focus from one field on the page to another (e.g., when a user
tabs out of a field or clicks on another field).
Oracle Utilities Application Framework Software Development Kit Developer's Guide 186
The pre/post After Field Update user exit is a good place to manipulate HTML elements (e.g., hiding/unhiding or enabling/
disabling) depending on the value entered by a user.
Note: The flowcharts above illustrate user exits in the Tab Page and List Grid templates only; these are the templates
in which most of your customizations will occur.
Accordion: accordionPage.jsp
Graph Panel: graphPanelExit.jsp
List Grid: listGridExit.jsp
Search Data: newSearchDataExit.jsp
Search Page: newSearchPageExit.jsp
Sub Panel: subPanelExit.jsp
Tab Page: tabPageExit.jsp
Oracle Utilities Application Framework Software Development Kit Developer's Guide 187
Tree Page: treePageExit.jsp
Template Structure
Each template has three main sections into which you insert your code.
User Variable Declaration contains global variable declarations. (Do not declare any global variables unless it is
absolutely necessary.)
User Function Declarations contains your own functions. Your own functions are not called from the corresponding
JSP file. Take coupling and cohesion into consideration when you design your functions.
Functions Called from the Corresponding HTML page contains functions that are called from the HTML page.
Uncomment the functions you need to use and add your code. You can find more technical information about the
behavior of these functions in the external template files.
Design Approach
Examine the partial template below to see how the external include file looks. As you might notice everything is
commented out. If you want to call a certain function, you have to uncomment the functions and/or sections. Please note
that only declared functions in the external files can be called from the HTML Page. To see the entire external file templates
or available functions, examine the "\cm_templates" folder under the application root directory.
<%@page contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="spl.tld" prefix="spl" %>
<spl:initializeLocale/>
<!--
******************************************************************
* *
* Copyright (c) 2000, 2007, Oracle. All rights reserved. *
* *
******************************************************************
* *
$#BSES* REVISION-INFO Start Exit, Do not modify - Dev. Only.
* $DateTime$
* $File$
* $Revision$
$#BSEE* REVISION-INFO End Exit, Do not modify - Dev. Only.
******************************************************************
-->
<script type="text/javascript">
/*
Replace With Your Code
*/
/*
Replace With Your Code
*/
Oracle Utilities Application Framework Software Development Kit Developer's Guide 188
/*
function extPreOnWindowLoadNoListBefore(){
//This should be used to set values/attributes when the page loads.
//This includes actions after a default.
//
//This function is called BEFORE SPL's internal functions are called
// Your Code
}
*/
The following discussion explains how the external file is included. The external file is a JSP file. This JSP is executed
with appropriate HTTP request header data from within the XSLT engine that creates the HTML from the UI meta-data.
The XSLT engine will output the rendered JSP code textually into the final HTML. If the file does not exist the server will
not include the external file, otherwise every defined function (uncommented) in the file will be included and called at the
appropriate times.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 189
Pay Plan Maintenance Page
Determine the name of the program component we need to extend. Right click on the page and select the menu option View
Source.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 190
Pay Plan Maintenance Page - View Source
View Source would open the page source in a text editor.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 191
JSP Source Code View - payPlanMaintPlanPage
From the menu bar or the program file information section you can identify the program name as payPlanMaintPlanPage
(look for the Program name in the source code comments).
Oracle Utilities Application Framework Software Development Kit Developer's Guide 192
* $PP_LBL - Pay Plan (element type='L' , jsName='PP_LBL')
* ...
* Widget Info:
* Widget_ID , Element Type - label info - label
* ...
* START_DT, IT - $START_DT - Start Date
function extPostOnWindowLoad(){
//This should be used to set values/attributes when the page loads.
//This includes actions after a default.
//This function is called AFTER SPL's internal functions are called
protectField("START_DT");
alert ("Start Date Field is disabled. Defaulted to Current Date.");
Note: You may need to delete the browser cache before refreshing the page.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 193
Pay Plan Main Page after implementing External User Exit
Fastpath: Refer to Field Level Security in the Administration Guide, Defining General Options chapter for
information about the data setup.
The following example code would be added to the extPreOnWindowLoad user exit:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 194
How-To
The following are some how-to examples of typical behavior utilizing some of the standard user exits.
The examples are written for cases of modifying new CM transaction pages, where the function definitions are put into
"extended JavaScipt" files (.xjs) that are meant to contain JavaScript user exits directly for a page.
If, on the other hand, an implementer wishes to modify the behavior of a shipped product page, each of the function below
have a corresponding "ext" function that can defined in a /cm/extXXX.jsp file corresponding to the desired page that will
fire after any product function call (see above example of hiding the Sequence column in the algorithm maintenance page).
function focusWidgetOverride() {
return null;
}
function focusWidgetOverride() {
return "TD_TYPE_DRLKY:0$TBL_NAME";
}
function focusWidgetOverride() {
return "LAST_NAME";
}
Note: These functions can be as simple or complicated as you want. You could conditionally return a field name or
null and this code will run each time the window loads. Also, if a tab page has a popup window or a search window
open as it is loading then the initial focus will not be set to the tab page but stay with the popup window
Oracle Utilities Application Framework Software Development Kit Developer's Guide 195
How Do I Mark Fields that Won't Make the Model Dirty?
In certain windows, we have a concept of a "locator" field which typically acts as a filter on some lists of the object you're
looking at. Examples are user group's filter on description, and several IB windows filter by date.
With the warning about loss of data when throwing away a dirty model, this results in the use of locator fields giving this
warning, which wouldn't be expected. In order to avoid this warning on locator fields, you can add a function like the one
that follows that enumerates the locator fields:
function ignoreModifiedFields(){
return ['START_DTTM']
}
function overrideDefaultTriggersFor_SRCH1() {
var triggers = {};
triggers["ACCT_ID"] = true;
triggers["SA_ID"]=true;
return triggers;
}
function notUppercaseFields() {
return ['ELEM_ATT$AT_NAME']
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 196
You can also provide a "global" override for an entire TabMenu by setting the shouldNotAutoUppercase variable to true:
function saveButtonEnablingOverride() {
return false;
}
function privatePostAddSucceeded() {
var model = parent.model;
var modeFlag = model.getValue('COMPL_NAV_MODE_FLG');
var navKey = model.getValue('COMPL_NAV_KEY');
var complSw = model.getValue('CMPLT_CLICKED_SW');
if (complSw && model.getValue('ENRL_STATUS_FLG') == '30') {
if (modeFlg && navKey){
if (modeFlag == 'G') {
parent.tabPage.gotoContext(navKey);
return false;
} else if(modeFlag == 'A') {
parent.tabPage.addContext(navKey);
return false;
}
}
}
return true;
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 197
How Do I Prevent the System from Setting Focus to a Widget
After an Error?
When a service receives an error and shows a message after calling a back-end service, the browser attempts to set focus to
the relevant widget in error. If you don't need this behavior, you can define the TabMenu variable dontSetFocusOnError to
boolean "true.
Example:
function dontCopyKeyNames_ENRL_FLD() {
return ['SEQ_NUM']
}
function initializeNewElement_ENRL_LOG(newElement) {
newElement.set('ENRL_LOG_TYPE_FLG', 'USER');
newElement.set('USER_INFO', parent.model.getValue('CURRENT_USER_INFO'));
}
Note: The default Sequence Number functionality will default the next nearest tens value from the highest sequence.
The defaulting will do nothing after the sequence reaches the highest number it can hold.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 198
In the user exit file of the Tab Menu - not the main Page or the List Grid - copy this JavaScript code:
function initializeNewElement_LIST_NAME(newElement) {
var myListName = "LIST_NAME";
var myListSeqName = "FIELD_NAME";
var myListMaxSeq = 999;
defaultSequenceNumber(myListName,myListSeqName,myListMaxSeq,newElement)
}
</SCRIPT>
<SCRIPT src="/zz/defaultSequenceNumber/defaultSequenceNumber.js"></SCRIPT>
<SCRIPT>
For LIST_NAME, substitute your List Grid's list name. Be careful not to lose that underscore [ _ ] just in front of LIST_
NAME in the first line! Remember that JavaScript is case-sensitive and make sure that you use all UPPERCASE letters
as shown here.
For FIELD_NAME, substitute the name of your sequence field, whatever that might be in your List. Don't lose the
quotes [ " ] ! Again, use all UPPERCASE letters.
function overrideErrorTabPage_BPA() {
return 'bussProcessAssistantStepPage';
}
addIgnoreFieldsFor_ADDRESS1_SRCH = function(fields) {
fields['CITY_SRCH'] = true
}
addIgnoreFieldsFor_PER_ID = function(fields) {
fields['ENTITY_NAME_SRCH'] = true
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 199
How Do I Disregard Unwanted Search Result Columns?
When you accept the result of a NOLOAD search the system tries to populate the selected search result row into the current
model. Sometimes this doesn't make sense e.g. because there is no corresponding attribute for a display-only column. You
can exclude a column from being returned as part of a search result by defining the search client's (Tab Page or Search
window) function ignoreResultColumns() in the corresponding page's user exit file. Return an object with keys specifying
attributes and values all set to boolean "true".
Example:
function ignoreResultColumns() {
return { ADDRESS1: true, CITY: true, POSTAL: true };
}
Since Searches can be shared by many search clients, it is possible that some clients want to get a specific column, but
others don't. In that case, define the TabMenu function ignoreResultColumnsFor_<service> as above.
Example:
function ignoreResultColumnsFor_CILCCOPS() {
return {CONT_OPT_TYPE_CD: true}
}
</SCRIPT>
<SCRIPT src="/zz/formatValue/formatValue.js"></SCRIPT>
<SCRIPT>
Now, you can start using the function to format a value. To use this function, you need to pass in both the value and the
format into the function.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 200
IAddInterceptor Interface
This interface defines the processing plug-in spots before or after invoking a service in add mode.
Interface com.splwg.base.api.serviceinterception.IAddInterceptor
Methods
IChangeInterceptor Interface
This interface defines the processing plug-in spots before or after invoking a page service in change mode.
Interface com.splwg.base.api.serviceinterception.IChangeInterceptor
Methods
Oracle Utilities Application Framework Software Development Kit Developer's Guide 201
PageBody aboutToChange(RequestContext, PageBody)
This method is called before the service invoked in change mode.
Input
RequestContext - contains session parameters, such as, language cd, user id and etc.
Input/Output
PageBody - this object contains the information that is to be submitted to the underlying service.
Return value
PageBody or null - if a page body is returned, this is considered the result of the invocation and the underlying service will
not be called. If null is returned, the underlying service will be invoked normally.
Throws
InteceptorError - throw this exception when an error occurs.
InterceptorWarning - throws this exception to signal an application warning
IDeleteInterceptor Interface
This interface defines the processing plug-in spots before or after invoking a service in delete mode.
Interface com.splwg.base.api.serviceinterception.IDeleteInterceptor
Methods
Oracle Utilities Application Framework Software Development Kit Developer's Guide 202
RequestContext - contains session parameters, such as, language cd, user id and etc.
Input/Output
PageBody - the data to be deleted.
Return value
Boolean - indicates whether or not to continue processing of the service. If true, continue with the normal underlying
invocation. If false, do not continue (but the service returns "success" to the client invoker).
Throws
InterceptorError - throw this exception when an error occurs.
InterceptorWarning - throws this exception to signal an application warning
IReadInterceptor Interface
This interface defines the processing plug-in spots before or after a service retrieves information.
Interface com.splwg.base.api.serviceinterception.IReadInterceptor
Methods
Oracle Utilities Application Framework Software Development Kit Developer's Guide 203
Throws
InterceptorError - throw this exception when an error occurs.
InterceptorWarning - throws this exception to signal an application warning
InterceptorError class
The class com.splwg.base.api.serviceinterception.InterceptorError subclasses the java.lang.Exception class. This class
contains information regarding an error condition that occurred during the pre/post processing plug-in. This exception is
caught by the framework and is used to build the appropriate application error object.
Attributes
Message Category
Message Number
List of Parameters (Strings) and types
Methods
Oracle Utilities Application Framework Software Development Kit Developer's Guide 204
void setMessageParameterTypeFlags(List
messageParameterTypeFlags)
Set the message parameter type flags list. The size should match the message parameters list.
InterceptorWarning class
The class com.splwg.base.api.serviceinterception.InterceptorWarning subclasses the java.lang.Exception class. This class
contains information regarding one or more warning conditions that occurred during the pre/post processing plug-in. This
exception is caught by the framework and is used to build the appropriate application warning object(s).
Attributes
List of warning server messages
Constructors
InterceptorWarning(ServerMessage warningMessage)
Create a new InterceptorWarning with the given warning message as its sole message
InterceptorWarning(List warningMessages)
Create a new InterceptorWarning with the given List of warning messages
Methods
RequestContext Methods
Class com.splwg.base.api.service.RequestContext includes the following accessor methods:
String getLanguageCode()
Returns the current user's language code
String getUserId()
Return the user id
Oracle Utilities Application Framework Software Development Kit Developer's Guide 205
Data Objects
Both PageHeader and PageBody are "wrappers" on underlying Maps that hold datatypes of various types, keyed by field
names (Strings). The valid field names for a service are described in the service meta info file (an xml document). Null
values are not allowed; use empty strings to represent missing values (e.g. for null date).
Note that most system datatypes are represented in these Java objects as simple Strings. Note the following:
Booleans are represented by the Java Boolean class
Date values are represented as Strings in the format YYYY-MM-DD
Date/Time values are represented as Strings in the format YYYY-MM-DD-HH:MM:SS
Time values are represented as Strings in the format HH:MM:SS
BigInteger values are represented as Java BigInteger values
BigDecimal and Money values are represented as Java BigDecimal values, with the appropriate scale.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 206
PageHeader
The methods for class com.splwg.base.api.service.PageHeader are described above.
PageBody
Class com.splwg.base.api.service.PageBody implements the methods described above. In addition, it supports the following
methods:
ItemList
Class com.splwg.base.api.service.ItemList is the Java representation of a list header and list children objects. The methods
are as follows:
ListHeader getHeader()
Return the list header object.
String getName()
Return the ItemList's name
List getList()
Return the java.util.List of ListBody child objects.
ListHeader
The class com.splwg.base.api.service.ListHeader is functionally equivalent to the class PageHeader, above.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 207
ListBody
The class com.splwg.base.api.service.ListBody is functionally identical to the class PageBody, above. In addition, it has this
useful method:
String getActionFlag()
Return the flag describing the pending action for this ListBody (e.g. add, change, delete).
CMServiceConfig.xml structure
The ServiceConfig.xml and CMServiceConfig.xml will look similar to the following:
<ServiceInterceptors>
<Service name="CMLPXXXX">
<Interceptor action="add">
com.splwg.interceptor.CMLPXXXXAddInterceptor
</Interceptor>
<Interceptor action="change">
com.splwg.interceptor.CMLPXXXXChangeInterceptor
</Interceptor>
</Service>
</ServiceInterceptors>
The above example illustrates how interceptors are defined for the service CMLPXXXX. You can define one or more
interceptors, depending on the action, for each service. The valid actions are "add", "change", "delete", and "read".
Note: It is valid to have the same interceptor class for more than one action as long as the class implements the
corresponding interceptor interface.
Application Logs
Logging has many purposes. Notably, it allows tracing of what is happening when something goes wrong. However, a user/
developer does not always want to see EVERY log entry-besides clutter, it may slow down the application. In this light, the
framework has wrapped the powerful and flexible log4j logging framework as an API. There are two important aspects:
Placing logging statements within application code so that logging entries may be created at runtime.
Configuring logging at runtime so that the appropriate logging entries are created and directed to the appropriate log
destination.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 208
Add a constant referencing the logger for the class. By convention logger should be named "logger" and should pass the
declaring class as its argument. For example, a logger in the Adjustment_CHandler class would be declared as follows:
Add entries with the appropriate logging level. The levels are: "debug", "info", "warn", "error" and "fatal". The following
will log a warning entry to the log:
In general, we expect entries of level "info" or more severe to be rare and therefore not to impose a substantial
performance penalty. However, "debug" entries we can expect to be very fine grained and that they usually will not find
their way to actual logs but will be filtered out via runtime configuration. To lessen the performance impact of debug
logging, the logging statement should be wrapped as follows:
if (logger.isDebugEnabled()) {
logger.debug("Processing adjustment " + adjustment.getId());
}
There are times when you want to know how long code block takes to execute. In general, the logging provides the time
each log statement is issued. However, it is clearer to see an actual elapsed time of some process being investigated. In
this case, there are some additional methods on the logger:
debugStart(message) or infoStart(message)
debugTime(message, start) or infoTime(message, start)
This will cause each statement to be logged, plus the final "End Process" statement will give the elapsed time since
debugStart was called.
Please refer to the JavaDocs on the com.splwg.shared.logging.Logger class for more detail.
Property Configuration
Control of log4j occurs based on properties typically set in the log4j.properties file in the application classpath. You can
change the log level of a given logger in this file. Note, however, that values may be overridden on the command line by
specifying system properties (e.g. via "-Dlog4j..."). Note that "inheritance" of logger levels works such that (in our standard
of qualified class name as the logger name) you can change a whole package's log level by specifying only a portion of the
Oracle Utilities Application Framework Software Development Kit Developer's Guide 209
logger name. Note that you may commonly desire to enable ("global") debug logging on your local environment. To do this,
you can simply change the line
log4j.logger.com.splwg=info
to
log4j.logger.com.splwg=debug
Trace Flags
Trace flags allow for specialized logging that cuts across many classes. They can be set for user requests by entering
the online system in "debug" mode and setting the "trace" flags appropriately. Likewise, they can be set in batch
either by interactive prompts for the trace flag values when a job starts or by setting system property values. See the
JobSubmitterConfiguration class for specific system property names.
traceProgramStart, traceProgramEnd, traceProgramStandardOut-These parameters are specific to COBOL programs and
will cause entries for the start and end of program execution and enable any embedded logging statements within the
COBOL code.
traceSQL-Causes special detail of SQL being submitted. This can be useful when troubleshooting performance problems.
traceTime-This can only be enabled for online requests or JUnit tests by setting traceTime(true) on the request context.
Enabling time tracing will cause special profiling entries to be placed in the application log for the purpose of attributing
request latency to the various layers of the application or to specific SQL statements. These entries are queued in
memory until after profiling entries are no longer being generated and then spooled to the logs so as not to corrupt the
performance instrumentation with logging overhead. The ProfilingReport standalone Java program can be run to post-
process these logs, or a portion of them and generate a report.
Rationale
In order to make it easier for programmers working on the same codebase to easily read each other's (and their own!)
code, we need to enforce certain standard coding conventions. These conventions will also be helpful when comparing
code revisions under version control, as the code should be formatted consistently and no irrelevant formatting-related
differences will appear in the diff.
Guidelines
First, Sun has their own code standards guidelines here: http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html.
Like most coding guidelines, these are quite reasonable and differ only in minor details from other guidelines.
The web page http://geosoft.no/development/javastyle.html also has some very nice tips. Note that we won't prefix instance
variable names with underscores--instead we use Eclipse syntax coloring to make ivars easily visible.
We use the prefix fetch in method names in entity implementation classes, in order to perform object navigations that aren't
already defined by Hibernate mappings.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 210
Here are some additional notes:
Not surprisingly, a lot can be learned from good Smalltalk style. The books "Smalltalk With Style" (Klimas, Skublics,
Thomas) and "Smalltalk Best Practices Patterns" (Kent Beck) provide a lot of good ideas for code organization and naming
that are applicable to Java as well as Smalltalk.
All code should be:
Written with tabs equal to 4 spaces, not "hard" tabs. Each level of indentation should be one "tab".
Generally free of hard-coded "magic" strings or numbers (e.g. max number of items in some list). If you need such a string
or number value, you should use (or create) a constant or property.
Classes should use specific, not package-based imports, where practical. I.e. import com.foo.UsefulClass, not com.foo.*.
Variables should generally be private. Only create accessor (e.g. get/set) methods when absolutely needed ("Dont reveal
your private parts").
Prefix "getter" methods with "get", e.g. "getFoo()", setters with "set", e.g. "setBar(aBar)". Don't use "Flag" or "Switch",
or abbreviations thereof, e.g. "getAllowedSw()" should be "getIsAllowed(), and "setAllowedSw(aBoolean)" should be
"setIsAllowed(aBool)".
Use camel-case instance and parameter variable names, without underscore prefixes or suffixes (do use uppercase for
constants, as suggested in the guidelines reference above). Instance variables start with lower-case letters.
Methods should generally be public or private (again, to allow future subclassing). Use of interfaces is encouraged to
declare useful sets of public methods.
Don't abbreviate except for standard industry abbreviations (e.g. HTML, HTTP). Use long, meaningful class, method, and
variable names.
Methods should be short and clear. Instead of placing comments before a section of code in a method, rather create another
method that describes what is being done by the method name.
When using Java API collections, reference them through generic interfaces, not specific implementation classes, e.g.
This lets you change your mind about implementation (e.g. ArrayList to LinkedList) without breaking any code.
Naming Standards
General guidelines
Don't use reserved java words
Don't use spaces
Don't abbreviate
Don't use punctuation
Don't start the name with a number
Here are our project guidelines for naming properties:
Generally, don't abbreviate. The exceptions are SA, SP when the name would get too long if written as e.g.
ServiceAgreement as part of a much longer field name
Oracle Utilities Application Framework Software Development Kit Developer's Guide 211
In line with the above, spell out amount and total
Boolean values (SW) are prefixed with is, has, can, are, or should, according to what is grammatically correct.
Date fields end with Date
Time fields end with Time
Datetime fields end with DateTime
Id is spelled Id
Don't include a final Flag (FLG) or Code (CD)
Use min instead of minimum, and max instead of maximum
Can be generic- that is, for the field BILL_STATUS, you can just name it status
Class Name
The class name for a collection includes the owning entity name and the collection name in singular form.
<owning_entity><collection_name_in_singular_form>
Examples:
AdjustmentTypeAlgorithm
AdjustmentTypeCharacteristic
BillableChargeTemplateLine
Collection Name
For collections, the one-off generation created a large number of collection names. Many of these are overly verbose, and
should be shortened. Simply modify the collectionName in the entity annotation. Here are guidelines:
Shorten adjustmentTypeAlgorithms to algorithms
Shorten adjustmentTypeCharacteristics to characteristics (in rare cases you may have more than one kind of
characteristic, in which case you need more specific names)
Remove the owning entity name from the front of the collection name, e.g. billableChargeTemplateLines becomes lines
Oracle Utilities Application Framework Software Development Kit Developer's Guide 212
Lookup Naming Guidelines
Here are guidelines for naming Lookups (on the Lookup Field maintenance):
Be specific- the name MUST be unique across all lookups
Don't include a final standard suffix Flag or Lookup (The suffix Lookup is automatically added by the generator to the
classes generated for each Lookup field.)
Examples:
WO_STATUS_FLG -> writeOffStatus
STM_RTG_METH_FLG -> statementRoutingMethod
Here are guidelines for naming Lookups Value properties (on Lookup Value maintenance):
Try to word the name in a way that makes sense when prepended by is, and is also valid when standing alone as a constant.
(eg {isComplete, COMPLETE}, {isFrozen, FROZEN})
The name might match the english description of the lookup value.
Examples:
HOW_TO_USE_FLG : - -> subtractive
ITEM_STATUS_FLG : A -> active
DGRP_PRIO_FLG : 10 -> highest10
DGRP_PRIO_FLG : 20 -> priority20
Special Cases
Oracle Utilities Application Framework Software Development Kit Developer's Guide 213
Characteristic control class <type_entity>CharacteristicControl
Characteristic control collection characteristicControls
For example, the class name for characteristic control of Customer Contact Type is
CustomerContactTypeCharacteristicControl.
And the collection is defined as follows:
/**
* @version $Revision: #1 $
* @BusinessEntity (tableName = CI_CC_TYPE,
oneToManyCollections = { @Child (collectionName = characteristicControls,
childTableName = CI_CHTY_CCTY)})
*/
The above algorithms list will contain as elements the algorithms for that algorithm type.
To sort the above query by the algorithm's code/id:
The above queryResults list will contain as elements instances of the interface QueryResultRow. Each query result row
will have two values, keyed by "algorithm" and "algorithmId". The list will be ordered (on the database) ascending by the
algorithm's IDs.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 214
Since HQL works with the entity's properties instead of the tables' column names, there may be extra research required
when writing queries. The source of the property information is in the hibernate mapping document for each entity class-
they are documents that exist in the same package as the entity, have the same root file name as the entity's interface, and
end with .hbm.xml. These files will give the list of properties available for each entity that can be referenced when writing
HQL.
More information can be found in the JavaDocs associated with the Query interface.
Examples
Even with all of the above, there are a few cases that stand out with possibly needing examples in order to help. Notably,
dealing with language entries and lookups may be confusing.
Here is an example of selecting all algorithm types where the description is like some input:
The algorithmTypes list will contain as elements the algorithm types whose description is like likeDescription. Note that the
string likeDescription will have a trailing '%' appended when it is bound to the query.
Here is an example of selecting particular lookup values, with descriptions like an input value:
The list results will contain QueryResultRows, with values keyed by "lookupValue" and "description".
Union queries
You may note that hibernate's HQL does not allow unions, as this does not reconcile with the object oriented approach
of HQL. However, as this can be a common technique to apply, a programmatic union has been provided in the Oracle
Utilities Application Framework. The application will actually open two cursors and flip back and forth between rows from
each cursor when each would be the next one, based upon the order by clause. This should at most read one extra row from
each cursor opened than may be needed (in the case of limited maximum rows).
In order to union two queries, they must have identical result columns, order by clauses, and max rows setting. Note that
some of the properties of the union query be modified directly, leaving the individual queries to omit those properties.
Creating a union query is simple. Given two queries that need to be unioned together, simply issue:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 215
UnionQuery union = query.unionWith(query2);
If a third (or later) query needs to be unioned, add it to the union directly:
union.addQueryToUnion(query3);
Performance
In order to evaluate the performance of HQL queries, it is necessary to first run the HQL through the hibernate engine at
run-time in order to produce the equivalent SQL. First, code the initial HQL into the application or a unit test or standalone
executable program. Start the application or test program with SQL tracing turned on. When the HQL under construction
executes, grab the SQL from the log/console. Then follow the directions in ??? 07 SQL Programming Standards to check
the performance of the SQL.
In general, most of the advice under the SQL programming standards applies equally for coding HQL when applicable at
all.
Raw SQL
In rare cases, it may be necessary to forgo the use of HQL and instead use raw SQL. This is not a preferred approach, as the
data returned will not be Java entities, but columns of primitive data types. However, for possible performance reasons (no
db hints are allowed in HQL) or if a table is not mapped into a Java entity, this approach exists.
There are parallel methods available on subclasses of GenericBusinessObject that create PreparedStatements, instead of
Query objects. So, instead of createQuery, the method createPreparedStatement should be called on a Raw SQL statement.
The PreparedStatement is similar to the regular jdbc PreparedStatement, but has some extra functionality, and a slightly
different interface so that it is similar to the regular HQL Query interface (they are interchangeable in some cases).
The main difference is that the prepared statement is created with raw SQL. Use the actual table and column names instead
of the Java entity names and property names. Also, the select clause must exist as in normal SQL but not HQL.
Additionally, this break-out into raw SQL allows SQL statements that update table data. Again, this is normally frowned
upon, and instead should be done by entity manipulation. However, in cases where a set-based SQL could update many
rows at once, this option is available, whereas HQL is ONLY meant for querying without any updates.
For more help on constructing raw SQL queries please see SQL Programming Standards.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 216
Prerequisite
This document assumes that you have a basic knowledge of SQL syntax and database functions.
Selection List
If a list of fields is to be returned, specify them prefixed by their table's alias name as specified in the From Clause.
Use the DISTINCT option when the result list of records may contain duplicate rows in respect to the specified list of
fields AND only one copy of the duplicated rows is needed.
For top-level batch programs, always specify the WITH HOLD keyword on the main SQL of a cursor based processing.
This is to keep the cursor open after a commit or rollback. Without this, main cursor will be closed and fetch of the next
record or restart processing will fail (specific to DB2) with SQL error 501.
Database-specific Features
Oracle
Oracle7 and later provides new approach for optimization: cost-based optimization (CBO). CBO evaluates the cost to,
or impact on, your system of the execution path for each specific query and then select the lowest-cost path. The CBO
was designed to save you the trouble of fiddling with your queries. Occasionally, it is not giving you the results you want
and you have exhausted all other possible problem areas, you can specify hints to direct the CBO as it evaluates a query
and creates an execution plan. If you have used hints before, you know that a hint starts with /*+ and ends with */. A hint
applies only to the statement in which it resides; nested statements consider as separate statement and require their own
hints. Furthermore, a hint currently has a 255-character limit. Since the use of hint is database-specific, we should make
use of Database Functions to accomplish it.
The most effective hints for use with the CBO are:
FULL - tells the optimizer to perform a full table scan on the table specified in the hint
SELECT /*+FULL(table_name)*/ COLUMN1,COLUMN2.....
Oracle Utilities Application Framework Software Development Kit Developer's Guide 217
INDEX - tells the optimizer to use one or more indexes for executing a given query.
Note: If you just want to ensure the optimizer doesn't perform a table scan, use INDEX hint without specifying an
index name and the optimizer will use the most restrictive index. A specific index should not be used as the actual
index name may differ on the client's site.
SELECT /*+INDEX(table_name index_name1 indexname2...) */
COLUMN1, COLUM2
ORDERED - tells the optimizer to access tables in particular order, based on the order in the query's FROM clause
(often referred to as the driving order for a query)
SELECT /*+ORDERED*/ COLUMN1, COLUMN2
FROM TABLE1, TABLE2
ALL_ROWS - tells the optimizer to choose the fastest path for retrieving all the rows of a query, at the cost of
retrieving a single row more slowly.
SELECT /*+ALL_ROWS*/ COLUMN1, COLUMN2...
FIRST_ROWS - tells the optimizer to choose the approach that returns the first row as quickly as possible.
Note: the optimizer will ignore the first rows hint in DELETE and UPDATE statements and in SELECT statements
that contain any of the following: set operators, group by clauses, for update clause, group functions, and the distinct
operators.
SELECT /*+FIRST_ROWS*/ COLUMN1, COLUMN2...
USE_NL - tells the optimizer to use nested loops by using the tables listed in the hint as the inner (non-driving) table
of the nested loop. Note: if you use an alias for a table in the statement, the alias name, not the table name, must
appear in the hint, or the hint will be ignored.
SELECT /*+USE_NL(tableA table B) */ COLUMN1, COLUMN2...
Hints are an Oracle specific feature and are not supported by the DB2 SQL syntax.
If you need to add a hint to your SQL make sure that a different SQL version is used for DB2 where the hint is not used.
Base product developers should not duplicate their SQL in this case but rather use the special database functions file
"dbregex.txt". In this file you should add a new hint-code that in Oracle translates into the specific hint whereas in DB2 it
translates into an empty string.
FROM Clause
Any table that has least one of its fields specified in the Selection List and/or any table that is directly referred to in the
Where Clause (excluding sub-selects if any) must be specified in this section.
Label each table with a meaningful short alias and use this alias to reference the table anywhere in the SQL.
WHERE Clause
Oracle Utilities Application Framework Software Development Kit Developer's Guide 218
Note that there is no such thing as "conditional" join where the only join statement for a table is under a condition.
In cases where the condition is not met and thus the join is not performed, one would end up with the same problem
described previously.
The final result set is built up by taking the full population of the tables involved and applying the restricting criteria
to it one after another where the intermediate result population of one step is the input for the next step. Therefore, it is
recommended to specify the most restrictive criteria first so that at the end of one step, lesser records are processed in the
next step.
This is of course a very schematic and simplified way to describe the internal process. This is not necessarily how the
database is actually processing the statements. However, setting up the criteria as described would direct the database to
use the right path.
Use of Sub-Selects
When you need to further test each processed record in the Where clause for meeting an additional condition, AND that
condition can NOT be checked directly on the Where clause level, you probably need a sub-select.
As it is performed once for each outer level record it is considered as quite an expensive tool. Therefore if the criteria
checked in a sub-select can be moved to the outer where clause level, it is preferable. If you still need to use a sub-select,
it is very important to restrict the outer where clause population to the very minimum possible so that lesser records
would need to be further checked for the sub-select condition.
When no value needs to be returned from the sub-select query but rather simply use it to check if a certain condition is
true or false, use the EXISTS function as follows:
Select ...
From ...
Where ... AND EXISTS (<sub-select>)
A sub-select query may refer to any value of the outer level record as its input parameters. Notice that if your sub-select
does NOT refer to any of the processed record fields, it means that the result set of the sub-select would be the same for
ALL the processed records.
Note that this could, but not necessarily, be an indication that your sub-select is set up wrong. One case where it is
definitely wrong is when the sub-select result is input to an EXISTS function.
Use of in Function
Whenever a field needs to be tested against a list of valid values it is recommended to use the IN function and not
compare the field against each and every value.
Wrong way:
Select ...
From ...
Where ... (A = '10' or A='20' or A='30')
Right way:
Select ...
From ...
Where ... A IN ('10','20','30')
Oracle Utilities Application Framework Software Development Kit Developer's Guide 219
Use of Database Functions
Not all database functions available for one database are valid for others. Make sure that when you do use a database
function the SQL works properly on every database supported by the product.
Avoid using LIKE as this will cause table scans. To achieve the 'LIKE' function where the first part of the string is
specified, e.g., "CM%", BETWEEN may be used with the input criteria padded with high and low values.
Other
Depending on the data distribution, search on optional index column will likely to cause time out. See example -
Select BSEG_ID
From CI_BSEG
Where MASTER_BSEG_ID = &IN.MASTER-BSEG-ID
For such cases, consider additional restrictions or re-create the index to become composite - MASTER_BSEG_ID +
BSEG_ID.
Sort Order
When a result list should be displayed in a specific order, sorting should take place on the database level and NOT on
the client. This is especially important in cases when the list cannot be returned in full but rather in batches of records.
Sorting each batch of records separately would not guarantee the sort order between records of different batches.
Columns in the sort order list must be specified in the selection list.
Prefix each field used in this clause with its table's alias name.
Explicitly specify whether sorting should be ascending or descending and do not rely on database defaults.
Grouping
When a set of records needs to be grouped together by a simple and straightforward condition, it is recommended to use
the database Group By Clause. In this case only the final summarized records are to be returned to the client resulting in
a lesser number of database calls as opposed to processing the full list let alone a simpler program without any special
grouping logic.
Existence Checks
The common technique used to check whether a certain condition is met or not, obviously when no data needs to be
returned, is simply COUNT how many records match that condition. A zero number indicates that no record has met that
condition.
Notice that this is not very efficient as we are asking the database to scan the records for an accurate number that we
don't really care about. All we really want to know if there is at least one such record and NOT how many they are.
When the tables involved are of low volume there should be no problem using this technique. It is very simple and uses
common SQL syntax to all databases.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 220
However, when that condition is checked against a high volume table that many of its records meet that condition,
scanning all the matching records to get a count we don't need should be avoided.
In this case use the EXISTS function as follows:
Select 'x'
From <The main table of the searched field, where it is defined as the PK of that table>
Where <search field> = <search value> and
EXISTS
(<sub-select with the desired condition. This is the high volume table>);
For example :
Select 'x'
From CI_UOM
Where UOM_CD = input UOM_CD and
EXISTS (select 'x'
From CI_BSEG_CALC_LN
Where UOM_CD = input UOM_CD);
If this does not work for your special case, use the following option :
Select 'x'
From CI_INSTALLATION
Where EXISTS
(<sub-select with the desired condition>) ;
Remember : This type of existence check using the Installation Options record should only be used in rare cases and
should be consulted with the DBA first before implementation.
Note that we use CI_INSTALLATION as this table has only one row.
Decimal Delimiter
In Europe the decimal delimiter is often set to be comma character. DB2 database configured this way will return SQL
syntax error in the following cases:
select ....,1,
insert ....values(...1,2,3...)
insert ....values(...1 ,2,...)
order by 1,2,3
order by 1 ,2
update...set abc=1,def='XX'
case (? as varchar(50),12
To avoid this problem, surround the comma with spaces.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 221
Whenever Statement
Expand Cobol pre compiler function does not support WHENEVER statement.
Result Data
Once your SQL is ready, it is essential to test that it actually returns the expected result.
Create sample data for each condition checked by your SQL. Then execute the SQL and make sure it returns the expected
result for each case.
Overview
An SQL may perform reasonably well even if not efficiently written in cases where the volume of processed data is low,
like in a development environment. However, the same SQL may perform very poorly when executed in a real high volume
environment. Therefore, any SQL should be carefully checked to make sure it would provide reasonable performance at
execution time.
Obviously there could be many reasons for an SQL to perform poorly and not all of them are easy to predict or track.
In general, these could be subcategorized into two main groups:
Basic issues related to the SQL code. These may be missing JOIN statements, inefficient path to the desired data,
inefficient use of database functions, etc.
More complicated issues having to do with lack of indexes, database tuning and handling of high volume of data,
efficiency of I/O system etc.
The latter group of issues may only be truly tested on a designated environment simulating a real production configuration.
These performance tests are typically conducted by a team of database and operating system experts as part of a thorough
performance testing of a predefined set of process.
It is the first group of issues that can and should be tested by the programmer at this stage. This is done by analysis of the
SQL's Explain Plan result.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 222
Since the Cost Based optimizer relies on actual data volume statistics to determine the access path, to generate an accurate
Explain Plan using the cost based optimizer requires a database set up with the proper statistics of a real high volume data
environment.
Note: A cost based optimizer Explain Plan generated on an inadequate database, would be totally inaccurate and
misleading!
Obviously, our development database does not qualify as an optimal environment of cost based optimizations. Since the
Rule Based optimizer is not data dependant it would provide a more reliable Explain Plan for this database.
Note: An efficient rule based Explain Plan does not guarantee an efficient cost based one when the SQL is finally
executed on the real target database. However, a poor rule based Explain Plan would most probably remain such on a
database with a higher volume of data.
Note: When the SQL is complicated and mainly designed to process high volume tables it is recommended to also
analyze its Explain Plan on an appropriate high volume database.
SQL To Check
Adjust the SQL Statement:
Extract the tested SQL into the Toad SQL editor.
Replace the COBOL name of each Host Variable with the equivalent database identifier :b<n> where n is a unique
number identifying that host variable. If the same variable appears more than one in the SQL use the same database
host variable id in all occurrences.
Force the database to analyze the SQL in Rule Base mode by introducing the RULE database hint phrase.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 223
Adjust the SQL Statement
Generate the Explain Plan:
Position the cursor on the SQL area
Choose the "Explain Plan Current SQL" option on the SQL-Window menu. Alternatively, use CTRL+E.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 224
Explain Plan
Access Methods
Logically Oracle finds the data to read by using the following methods:
Full Table Scan (FTS). Using this method the whole table is read.
Index Lookup (unique & non-unique). Using this method, data is accessed by looking up key values in an index and
returning rowids where a rowid uniquely identifies an individual row in a particular data block.
Rowid. This is the quickest access method available Oracle simply retrieves the block specified and extracts the rows it
is interested in. Most frequently seen in explain plans as Table access by Rowid.
Cartesian Product
A Join is a predicate that attempts to combine 2 row sources. Cartesian Product is created when there are no join
conditions between 2 row sources and there is no alternative method of accessing the data. Typically this is caused by a
coding mistake where a join has been left out. The CARTESIAN keyword in the Explain Plan indicates this situation.
Join Order
A Join is a predicate that attempts to combine 2 row sources. We only ever join 2 row sources together. Join steps are
always performed serially even though underlying row sources may have been accessed in parallel. The join order makes a
significant difference to the way in which the query is executed. By accessing particular row sources first, certain predicates
may be satisfied that are not satisfied by with other join orders. This may prevent certain access paths from being taken.
Make sure the join between 2 tables is done via indexed fields as much as possible.
Also, if such an index exists, make sure you specify fields in the order they are defined by that index.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 225
Nested Loops
This is a common type of processing a join between 2 row sources. First we return all the rows from row source 1, then we
probe row source 2 once for each row returned from row source 1.
Row source 1
Row 1 -------------- -- Probe -> Row source 2
Row 2 -------------- -- Probe -> Row source 2
Row 3 -------------- -- Probe -> Row source 2
Row source 1 is known as the outer table. Row source 2 is known as the inner table. Accessing row source 2 is known
a probing the inner table. For nested loops to be efficient it is important that the first row source returns as few rows as
possible as this directly controls the number of probes of the second row source. Also it helps if the access method for row
source 2 is efficient as this operation is being repeated once for every row returned by row source 1.
Sort
Sorts are expensive operations especially on large tables where the rows do not fit in memory and spill to disk.
There are a number of different operations that promote sorts:
Order by clauses
Group by
Sort merge join
Note that if the row source is already appropriately sorted then no sorting is required. In other words, if the fields you sort
by happen to be defined by an Index in that particular order then sort operation is avoided. Therefore, whenever you see that
an explicit sort operation has taken place, check if it can be avoided by using an index or sometimes just by making sure
your are using an index's fields in the right order.
If no such index exists and the number of rows to be sorted is of high volume, please consult a DBA as this may justify
adding a new index.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 226
Varchar2(n) where n is "right sized" Varchar2(4000) for everything (just in case)
Assume array fetch of 100 rows, so array fetch buffer or 40,000 Assume array fetch of 100 rows, so array fetch buffer or 4,000,000
bytes. bytes.
Assume 25 open cursors, so 1,000,000 bytes of array fetch buffers. Assume 25 open cursors, so 100,000,000 bytes.
Assume connection pool with 30 connections 30MB. Assume connection pool with 30 connections 3GB.
NOT Null columns should be preferred over Null able columns. The reason is if you have an Index on a Null able
column then it would not be used by the SQL as the optimizer thinks that it would not find any values in some of the
columns so prefer a full scan.
As a workaround for columns with NULL data types the Index create SQL should look like:
Create INDEX ABC ON TAB1 (COLUMN1, 0);
This will make sure that in case the Column1 is null the optimizer will consider the value as 0 and leads to index scan as
compared to Full scans.
Always try to substitute the Bind Variables in a SQL with the actual constant value if there is only one possible. Having
too much Bind variables sometimes confuses the Optimizer to take the right access path. So this is good for the stability
of the SQL plans.
Fields which are foreign keys to other tables and are used in SQLs for the Join criterion are good candidates for creating
Indexes on.
Do not create any objects in the database of which the name may collide with any SQL reserved words.
Views are generally used to show specific data to specific users based on their interest. Views are also used to restrict
access to the base tables by granting permission only on views. Yet another significant use of views is that they simplify
your queries. Incorporate your frequently required, complicated joins and calculations into a view so that you don't have
to repeat those joins/calculations in all your queries. Instead, just select from the view.
Avoid creating views within views as it affects the performance.
Offload tasks, like string manipulations, concatenations, row numbering, case conversions, type conversions etc., to the
front-end applications if these operations are going to consume more CPU cycles on the database server. Also try to do
basic validations in the front-end itself during data entry. This saves unnecessary network roundtrips.
Always be consistent with the usage of case in your code. On a case insensitive server, your code might work fine, but it
will fail on a case-sensitive server if your code is not consistent in case.
Make sure you normalize your data at least to the 3rd normal form. At the same time, do not compromise on query
performance. A little bit of denormalization helps queries perform faster.
Consider indexing those columns if they are frequently used in the ORDER clause of SQL statements.
Use tools like Tkprofs and AWR Report for measuring the Performance of your SQLs.
In the SQL Explain Plans, usage of Nested Loops are good when there are table joins involved.
Always looks for Autotrace to measure the SQL plan as it is closer to the plan which the optimizer takes during the
actual execution of the SQL. This can be get easily through SQL Developer and other database monitoring tools.
While looking at the Autotrace Plans look for consistent gets and make sure they are low. The other thing reported by the
Autotrace is COST. Do not worry too much about cost if the Consistent gets is low and you are getting a desirable Plan.
Make sure that the Statistics are current and not stale while you are trying to Tune a SQL.
Having Secondary Unique Indexes help in achieving Index Unique scans. This will eliminate the Table scans. It is worth
trying and see if that makes a difference.
Oracle Optimizer executes the explain plans of a SQL from Inner to the outer area and from bottom to the top. So make
sure that the cardinality of the inner most Join criterion should be low.
Always keep in mind the usage of the SQL in a real production scenario where the data in the tables can go
exponentially. Make sure that the SQLs can handle it and the Explain plan should be accordingly tuned.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 227
Usage of <<, != make the Index NOT to be used. Instead of this use the greater than or less than statements.
If you wrap a column a column with some functions like TO_DATE, TO_CHAR, SUBSTR and so on then the Index on
the Column would not be used.
Avoid using UNION and make sure you use UNION ALL if possible. This will boost performance.
Using EXISTS , NOT EXISTS are better than using IN , NOT IN statements respectively.
Usage of Leading Hints helps in choosing what Table should be the first table in the join order.
/*+ LEADING(Table1 Table2) */
When writing comments within SQL statements make sure that the comments are not added at the beginning because
DB2 will not be able to parse it. You can instead put the Comments at the end and it will work. For Oracle this is not an
issue.
Additional Resources
Additional information on optimizing SQL in your OUAF applications can be found in the Oracle Utilities Application
Framework - Technical Best Practices whitepaper available on the My Oracle Support (MOS) Knowledge Base (article
560367.1).
Database Design
The objective of this document is to provide a standard for database objects (such as tables, columns, and indexes) for
products using Oracle Utilities Application Framework. This standard is introduced to insure clean database design, to
promote communications, and to reduce errors leading to smooth integration and upgrade processes. Just as Oracle Utilities
Application Framework goes thorough innovation in every release of the software, it is also inevitable that the product will
take advantage of various database vendors' new features in each release. The recommendations in the database installation
section include only the ones that have been proved by vigorous QA processes, field tests and benchmarks.
Naming Standards
The following naming standards must be applied to database objects.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 228
Table
Table names are prefixed with the owner flag value of the product. For customer modification CM must prefix the table
name. The length of the table names must be less than or equal to 30 characters. A language table should be named by
suffixing _L to the main table. The key table name should be named by suffixing _K to the main table.
It is recommended to start a table name with the 2-3 letter acronym of the subsystem name that the table belongs to. For
example, MD stands for meta-data subsystem and all meta data table names start with CI_MD.
Some examples are:
CI_ADJ_TYPE
CI_ADJ_TYPE_L
Note: A language table stores language sensitive columns such as a description of a code. The primary key of a
language table consists of the primary key of the code table plus language code (LANGAGUE_CD).
Note: A key table accompanies a table with a surrogate key column. A key value is stored with the environment id
that the key value resides in the key table.
Note: The tables prior to V2.0.0 are prefixed with CI_ or SC_.
Columns
The length of a column name must be less than or equal to 30 characters. The following conventions apply when you define
special types of columns in the database.
Use the suffix FLG to define a lookup table field. Flag columns must be CHAR(4). Choose lookup field names carefully as
these column names are defined in the lookup table (CI_LOOKUP_FLD) and must be prefixed by the product owner flag
value.
Use the suffix CD to define user-defined codes. User-defined codes are primarily found as the key column of the admin
tables.
Use the suffix ID to define system assigned key columns.
Use the suffix SW to define Boolean columns. The valid values of the switches are 'Y' or 'N'. The switch columns must be
CHAR(1)
Use the suffix DT to define Date columns.
Use the suffix DTTM to define Date Time columns.
Use the suffix TM to define Time columns.
Some examples are:
ADJ_STATUS_FLG
CAN_RSN_CD
Indexes
Index names are composed of the following parts:
[X][C/M/T]NNN[P/S]
Oracle Utilities Application Framework Software Development Kit Developer's Guide 229
X - letter X is used as a leading character of all base index names prior to Version 2.0.0. Now the first character of product
owner flag value should be used instead of letter X. For client specific implementation index in Oracle, use CM.
C/M/T - The second character can be either C or M or T. C is used for control tables (Admin tables). M is for the master
tables. T is reserved for the transaction tables.
NNN - A three-digit number that uniquely identifies the table on which the index is defined.
P/S/C - P indicates that this index is the primary key index. S is used for indexes other than primary keys. Use C to indicate
a client specific implementation index in DB2 implementation.
Some examples are:
XC001P0
XT206S1
XT206C2
CM206S2
Do not use index names in the application as the names can change due to unforeseeable reasons.
Sequence
The base sequence name must be prefixed with the owner flag value of the product.
Trigger
The base trigger name must be prefixed with the owner flag value of the product.
Note: When implementers add database objects, such as tables, triggers and sequences, the name of the objects should
be prefixed by CM. For example, Index names in base product are prefixed by X; the Implementers' index name must
not be prefixed with X.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 230
software uses a sequential key assignment mechanism. For sequential key assignment implementation, the DBMS sequence
generator is used in conjunction with Number Type ID columns.
Date/Time/Timestamp
Date, Time and Timestamp columns are defined physically as DATE in Oracle. In DB2 the DATE, TIME and
TIMESTAMP column types, respectively, are used to implement them. Non-null constraints are implemented only for the
required columns.
Number
Numeric columns are implemented as NUMBER type in Oracle and DECIMAL type in DB2. The precision of the number
should always be defined. The scale of the number might be defined. Non-null constraints are implemented for all number
columns.
Null Constraints
The Non-null constraints are implemented for all columns except optional DATE, TIME or TIMESTAMP columns.
Standard Columns
Oracle Utilities Application Framework Software Development Kit Developer's Guide 231
Owner Flag
Owner Flag (OWNER_FLG) columns exist on the system tables that are shared by multiple products. Oracle Utilities
Application Framework limits the data modification of the tables that have owner flag to the data owned by the product.
Version
The Version column is used to for optimistic concurrency control in the application code. Add the Version column to all
tables that are maintained by a Row Maintenance program irrespective of the language used (COBOL or JAVA).
Note: Developer's Note > All test data added to the system data tables must be prefixed by ZZ (all upper case) in
order for the installation and upgrade utility to recognize them as test data.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 232
Guidelines for System Table Updates
Properties Description
Tables SC_ACCESS_CNTL, SC USER, SC_USR_GRP_PROF, SC_USR_
GRP_USR, SC_USER_GROUP, SC_USER_GROUP_L
Initial Data User Group All SERVICES and default system user SYSUSER.
Upon installation the system default User Group All SERVICES is
given unrestricted accesses to all services defined in Oracle Utilities
Application Framework.
Note: Developer's Note> When a new service is added to the system, all actions defined for the service must be made available to the User Group All
SERVICES.
Currency Code
The ISO 4217 three-letter codes are taken as the standard code for the representation of the currency.
Properties Description
Tables CI_LANGUAGE
Initial Data United States Dollar (USD).
DB Process
Properties Description
Tables CI_DB_PROC, CI_DB_PROC_L, CI_DB_INSTR, CI_DB_INSTR_L, CI_
DB_INSTR_OVRD
Initial Data Copy DB Process (CL-COPDB). This DB process allows users to copy
a DB process from one database to another using Config Lab utility.
Display Profile
The Display Profile Code is referenced in User (SC_USER) table.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 233
Properties Description
Tables CI_DISP_PROF, CI_DISP_PROF_L
Initial Data North America (NORTHAM) and Europe (EURO).
Installation Options
Installation option has only one row that is shipped with the initial installation of the Oracle Utilities Application
Framework. The updatable columns in these tables are customer data and will not be overridden by the upgrade process
unless a special script is written and included in the upgrade process.
Properties Description
Tables F1_INSTALLATION, CI_INSTALL_ALG, CI_INSTALL_MSG, CI_
INSTALL_MSG_L, CI_INSTALL_PROD
Initial Data Option 11111.
Note: The system data owner of an environment is defined in the Installation Option. This Owner Flag value is stamped on all system data that is added to this
environment. The installation default value is Customer Modification (CM). This value must be changed in the base product development environments.
Language Code
Language code must be valid code defined in ISO 639-2 Alpha-3. Adding a new language code to the table without
translating all language dependent objects in the system can cause errors when a user chooses the language.
Properties Description
Tables CI_LANGUAGE
Initial Data English (ENG).
Properties Description
Tables CI_ROLE(L), CI_TD_VAL_ROLE
Initial Data F1_DFLT
Standards
When adding a new data, the owner flag value of the environment must prefix certain fields of these tables. For example,
when a developer adds a new algorithm type to an Oracle Utilities Business Intelligence development environment B1
Oracle Utilities Application Framework Software Development Kit Developer's Guide 234
should prefix the new Algorithm Type code. The fields that are subject to this rule are listed in Standard Data Fields
property.
The data that is already in these tables are not allowed for modification if the data owner is different from your
environment owner. This is to prevent the developers from accidentally modifying system data that belong to Oracle
Utilities Application Framework or other Base products. However, some fields are exempt from this rule and can be
modified by Customer Modification. These fields are listed in Customer Modification Fields property.
Note: Starting V2.2, we introduce a new system data upgrade rule - override Owner flag. If duplicate data rows (data
row with same primary key values) found at the time of upgrade, the owner flag values will get overridden. The lower
level application system data will override the upper level system data. For example, F1 overrides C1, F1&C1 overrides
CM etc. This rule will be applied to the following tables: CI_CHAR_ENTITY, CI_MD_MO_ALG, F1_BUS_OBJ_
ALG, F1_BUS_OBJ_STATUS_ALG, CI_MD_MO_OPT, F1_BUS_OBJ_OPT, F1_BUS_OBJ_STATUS_OPT, F1_
BUS_OBJ_STATUS, F1_BUS_OBJ_STATUS_L
Algorithm Type
Properties Description
Tables CI_ALG_TYPE, CI_ALG_TYPE_L, CI_ALG_TYPE_PRM, CI_ALG_
TYPE_PRM_L
Standard Data Fields Algorithm Type (ALG_TYPE_CD)
Customer Modification None
Algorithm
Properties Description
Tables CI_ALG, CI_ALG _L, CI_ALG_PARM, CI_ALG_VER
Standard Data Fields Algorithm (ALG_CD)
Customer Modification None
Application Security
Properties Description
Tables SC_APP_SERVICE, SC_APP_SERVICE_L, CI_APP_SVC_ACC
Standard Data Fields Application Service Id (APP_SVC_ID). CC&B product prior to version
2.0 will continue to use CI as prefix of the application service.
Customer Modification None
Batch Control
Properties Description
Tables CI_BATCH_CTRL, CI_BATCH_CTRL_L, CI_BATCH_CTRL_P, CI_
BATCH_CTRL_P_L
Standard Data Fields Batch Process (BATCH_CD),Program Name(PROGRAM_NAME)
Oracle Utilities Application Framework Software Development Kit Developer's Guide 235
Properties Description
Customer Modification
Next Batch Number (NEXT_BATCH_NBR), Last Update Instance
( LAST_UPDATE_INST), Last Update Date time (LAST_UPDATE_
DTTM). These columns are updated by the batch processes.
Batch Parameter Value (BATCH_PARM_VAL)
Business Object
Properties Description
Tables F1_BUS_OBJ, F1_BUS_OBJ_L, F1_BUS_OBJ_ALG, F1_BUS_OBJ_
OPT, F1_BUS_OBJ_STATUS, F1_BUS_OBJ_STATUS_L, F1_BUS_
OBJ_STATUS_ALG, F1_BUS_OBJ_STATUS_OPT, F1_BUS_OBJ_
TR_RULE, F1_BUS_OBJ_TR_RULE_L
Standard Data Fields Business Object (BUS_OBJ_CD)
Customer Modification
None
Business Service
Properties Description
Tables F1_BUS_SVC, F1_BUS_SVC_L
Standard Data Fields Business Service (BUS_SVC_CD)
Customer Modification
None
Characteristics
Properties Description
Tables CI_CHAR_TYPE, CI_CHAR_TYPE_L, CI_CHAR_ENTITY, CI_CHAR_
VAL, CI_CHAR_VAL_L
Standard Data Fields Characteristic Type CHAR_TYPE_CD)
Customer Modification
Adhoc Characteristic Value Validation Rule (ADHOC_VAL_ALG_
CD) on Characteristic Entity Table (CI_CHAR_ENTITY)
Data Area
Properties Description
Tables F1_DATA_AREA, F1_DATA_AREA_L
Standard Data Fields Data Area Code (DATA_AREA_CD)
Customer Modification None
Oracle Utilities Application Framework Software Development Kit Developer's Guide 236
Display Icon
Properties Description
Tables CI_DISP_ICON, CI_DISP_ICON_L
Standard Data Fields Display Icon Code (DISP_ICON_CD)
Customer Modification None
Properties Description
Tables CI_FK_REF, CI_FK_REF_L
Standard Data Fields FK reference code (FK_REF_CD)
Customer Modification None
Lookup
Properties Description
Tables CI_LOOKUP_FIELD, CI_LOOKUP_VAL, CI_LOOKUP_VAL_L
Standard Data Fields Field Name (FIELD_NAME)
Note: A new Feature option is defined through adding a value to EXT_SYS_TYP_FLG. The field value for this look up field must be prefixed by the Owner
flag value.
Map
Properties Description
Tables F1_MAP, F1_MAP_L
Standard Data Fields Map ode (MAP_CD)
Customer Modification None
Oracle Utilities Application Framework Software Development Kit Developer's Guide 237
Messages
Properties Description
Tables CI_MSG_CATEGORY, CI_MSG_CATEGORY_L, CI_MSG, CI_MSG_L
Standard Data Fields Message Category (MESSAGE_CAT_NBR)
Properties Description
Tables CI_MD_TBL, CI_MD_TBL_FLD, CI_MD_TBL_L, CI_MD_TBL_FLD_L,
CI_MD_FLD, CI_MD_FLD_L
Standard Data Fields
Table Name(TBL_NAME)
Oracle Utilities Application Framework Software Development Kit Developer's Guide 238
Properties Description
Table names must match with the physical table name or view name
in the database.
Field Name(FLD_NAME)
Field name must match with the physical column name in the
database unless the field is a work field. Field name does not have
to follow the prefixing standard unless the field is a work field or
customer modification field.
Customer Modification Audit Switches (AUDIT_INSERT_SW, AUDIT_UPDATE_SW, AUDIT_
DELETE_SW), Audit Program Name (AUDIT_PGM_NAME), Audit
Table Name (AUDIT_TBL_NAME), Override label (OVRD_LABEL)
Properties Description
Tables CI_MD_CONST, CI_MD_CONST_FLD
Standard Data Fields
Constraint Id (CONST_ID)
AA_CXXXXXP00 for Primary Constraints
AA_CXXXXXRnn for Foreign Key Constraints Where
AA : Product owner flag value
XXXXX : First 5 letters of the primary index name of the table
nn: integer 01..99
Customer Modification None
Properties Description
Tables CI_MD_MENU, CI_MD_MENU_L, CI_MD_MENU_ITEM, CI_MD_
MENU_ITEM_L, CI_MD_MENU_LINE, CI_MD_MENU_LINE_L
Standard Data Fields Menu Name (MENU_NAME), Menu Item Id (MENU_ITEM_ID), Menu
Line Id (MENU_LINE_ID)
Customer Modification None
Properties Description
Tables CI_MD_PRG_COM, CI_MD_PRG_LOC, CI_MD_SVC, CI_MD_SVC_L,
CI_MD_SVC_PRG, CI_MD_PRG_REF, CI_MD_PRG_MOD, CI_MD_
PRG_EL_AT, CI_MD_PRG_ELEM, CI_MD_PRG_SEC, CI_MD_PRG_
SQL, CI_MD_PRG_VAR, CI_MD_PRG_TAB
Standard Data Fields Program Component Id (PROG_COM_ID), Location Id (LOC_ID),
Program Component Name (PROG_COM_NAME), Service Name
(SVC_NAME), Navigation Key (NAVIGATION_KEY)
Customer Modification User Exit Program Name (USER_EXIT_PGM_NAME on CI_MD_
PRG_COM),
Oracle Utilities Application Framework Software Development Kit Developer's Guide 239
Meta data - Maintenance Object
Properties Description
Tables CI_MD_MO, CI_MD_MO_L, CI_MD_MO_TBL, CI_MD_MO_OPT, CI_
MD_MO_ALG
Standard Data Fields Maintenance Object Name (MO_NAME)
Customer Modification None
Properties Description
Tables CI_MD_WRK_TBL, CI_MD_WRK_TBL_L, CI_MD_WRK_TBLFLD, CI_
MD_MO_WRK
Standard Data Fields Work Table Name (WRK_TBL_NAME)
Customer Modification None
Properties Description
Tables CI_MD_SO, CI_MD_SO_L, CI_MD_SO_RSFLD, CI_MD_SO_
RSFLDAT, CI_MD_SOCG, CI_MD_SOCG_FLD, CI_MD_SOCG_
FLDAT, CI_MD_SOCG_L, CI_MD_SOCG_SORT
Standard Data Fields Search Object Name (SO_CD)
Customer Modification None
Navigation Option
Properties Description
Tables CI_NAV_OPT, CI_NAV_OPT_L, CI_NAV_OPT_CTXT, CI_NAV_OPT_
USG, CI_MD_NAV
Standard Data Fields Navigation Option Code (NAV_OPT_CD), Navigation Key
NAVIGATION_KEY)
Customer Modification Navigation Key Override (NAV_KEY_OVRD)
Properties Description
Tables CI_PORTAL_ZONE, CI_ZONE, CI_ZONE_L, CI_ZONE_PARM, CI_
ZONE_HDL, CI_ZONE_HDL_L, CI_ZONE_HDL_PRM, CI_ZONE_
HDL_PRM_L, CI_UI_ZONE
Oracle Utilities Application Framework Software Development Kit Developer's Guide 240
Properties Description
Standard Data Fields
Portal Code (PORTAL_CD), Zone Code (ZONE_CD), Zone Type
Code (ZONE_HDL_CD)
A new Zone can be added to the Product owned Portal Pages.
The existing Zones cannot be removed from the Product owned
Portal Pages.
Customer Modification Sort Sequence (SORT_SEQ)
Sequence
Properties Description
Tables CI_SEQ
Standard Data Fields Sequence Name (SEQ_NAME)
Customer Modification Sequence Number (SEQ_NBR)
Schema
Properties Description
Tables F1_SCHEMA
Standard Data Fields Schema Name (SCHEMA_NAME)
Customer Modification
None
Script
Properties Description
Tables CI_SCR, CI_SCR_L, CI_SCR_CRT, CI_SCR_CRT_GRP, CI_SCR_
CRT_GRP_L, CI_SCR_DA, CI_SCR_FLD_MAP, CI_SCR_PRMPT, CI_
SCR_PRMPT_L, CI_SCR_STEP, CI_SCR_STEP_L
Standard Data Fields Script Code (SCR_CD)
Customer Modification None
To do Type
Properties Description
Tables CI_TD_TYPE, CI_TD_TYPE_L, CI_TD_SRTKEY_TY, CI_TD_
DRLKEY_TY, CI_TD_SRTKEY_TY_L
Standard Data Fields To Do Type Code (TD_TYPE_CD)
Customer Modification Creation Batch Code (CRE_BATCH_CD), Route Batch Code (RTE_
BATCH_CD), Priority Flag (TD_PRIORITY_FLG)
Oracle Utilities Application Framework Software Development Kit Developer's Guide 241
XAI configuration
Properties Description
Tables CI_XAI_ADAPTER, CI_XAI_ADAPTER_L, CI_XAI_CLASS, CI_XAI_
CLASS_L, CI_XAI_ENV_HNDL , CI_XAI_ENV_HNDL_L, CI_XAI_
FORMAT, CI_XAI_FORMAT_L, CI_XAI_RCVR, CI_XAI_RCVR_L, CI_
XAI_RCVR_CTX, CI_XAI_RCVR_RSP, CI_XAI_RCVR_RGRP, CI_
XAI_SENDER, CI_XAI_SERNDER_L, CI_XAI_SNDR_CTX, CI_XAI_
OPTION
Standard Data Fields Adapter Id (XAI_ADAPTER_ID), Class Id (XAI_CLASS_ID), Envelope
Handler Id (XAI_ENV_HNDL_ID), XAI Format Id (XAI_FORMAT_ID),
Receiver Id (XAI_RCVR_ID), Sender Id (XAI_SENDER_ID)
Customer Modification Option Value (OPTION_VALUE on CI_XAI_OPTION)
Fastpath: The following XAI tables might have system data installed upon the initial installation but a subsequence system data upgrade process will not
update the content of these table unless the change is documented in the database upgrade guide : CI_XAI_RCVR, CI_XAI_RCVR_L, CI_XAI_RCVR_CTX,
CI_XAI_RCVR_RSP, CI_XAI_RCVR_RGRP, CI_XAI_SENDER, CI_XAI_SERNDER_L, CI_XAI_SNDR_CTX
XAI Services
Properties Description
Tables CI_XAI_IN_SVC, CI_XAI_IN_SVC_L, CI_XAI_SVC_PARM
Standard Data Fields To Do Type Code (TD_TYPE_CD), XAI Inbound Service Id (XAI_IN_
SVC_ID), XAI Inbound Service Name (XAI_IN_SVC_NAME)
Customer Modification
XAI_IN_SVC_ID, XAI_IN_SVC_NAME, XAI_VERSION_ID, POST_
ERROR_SW
Oracle Utilities Application Framework Software Development Kit Developer's Guide 242
CI_MD_TMPL / CI_MD_TMPL_L
CI_MD_TMPL_ELTY
CI_MD_TMPL_VAR / CI_MD_TMPL_VAR_L
CI_MD_VAR / CI_MD_VAR_DTL / CI_MD_VAR_DTL_L
CI_XAI_EXECUTER / CI_XAI_EXECUTER_L
Oracle Utilities Application Framework Software Development Kit Developer's Guide 243
Table Name Upgrade Action Description
CI_LOOKUP_VAL_L MG Lookup Field Value Language
CI_MD_ATT_TY RF MD Element Attribute Type
CI_MD_AT_DTL RF MD Element Attribute Type Detail
CI_MD_AT_DTL_L RF MD Element Attribute Type Detail Language
CI_MD_CONST MG Constraints
CI_MD_CONST_FLD MG Constraint Fields
CI_MD_CTL RF Generator Control
CI_MD_CTL_L RF Generator Control Language
CI_MD_CTL_TMPL RF Generator Control Template
CI_MD_ELTY RF MD Element Type
CI_MD_ELTY_AT RF Element Type Attributes
CI_MD_ELTY_L RF Element Type Language
CI_MD_FLD MG Field
CI_MD_FLD_L MG Field Language
CI_MD_LOOKUP RF MD Lookup Field Value
CI_MD_LOOKUP_F RF MD Lookup Field
CI_MD_MENU MG Menu Information
CI_MD_MENU_IMOD MG Menu Item Module Maint
CI_MD_MENU_ITEM MG Menu Item
CI_MD_MENU_ITEM_L MG Menu Item Language
CI_MD_MENU_L MG Menu Language
CI_MD_MENU_LINE MG Menu Line
CI_MD_MENU_LINE_L MG Menu Line Language
CI_MD_MENU_MOD MG Menu Product Components
CI_MD_MO MG Maintenance Object
CI_MD_MO_ALG MG Maintenance Object Algorithm
CI_MD_MO_L MG Maintenance Object Language
CI_MD_MO_OPT MG Maintenance Object Option
CI_MD_MO_TBL MG Maintenance Object Table
CI_MD_MO_WRK MG Maintenance Object Work Tables
CI_MD_MSG RF MD Message
CI_MD_MSG_L RF MD Message Language
CI_MD_NAV MG Navigation Key
CI_MD_PDF RF Predefined Fields
CI_MD_PDF_VAL RF Predefined Values
CI_MD_PRG_COM MG Program Components
CI_MD_PRG_ELEM MG UI Page Elements
CI_MD_PRG_EL_AT MG UI Page Element Attributes
CI_MD_PRG_LOC MG Program Location
CI_MD_PRG_MOD MG Program Module
CI_MD_PRG_SEC MG UI Page Sections
CI_MD_PRG_SQL MG MD SQL Meta Data
CI_MD_PRG_TAB MG UI Tab Meta Data
CI_MD_PRG_VAR MG Program Variable
CI_MD_SO MG Search Object
CI_MD_SOCG MG Search Object Criteria Group
CI_MD_SOCG_FLD MG Search Object Criteria Group Field
Oracle Utilities Application Framework Software Development Kit Developer's Guide 244
Table Name Upgrade Action Description
CI_MD_SOCG_FLDAT MG Search Object Criteria Group Field Attribute
CI_MD_SOCG_L MG Search Object Criteria Group Language
CI_MD_SOCG_SORT MG Search Object Criteria Group Result Sort Order
CI_MD_SO_L MG Search Object Language
CI_MD_SO_RSFLD MG Search Object Result Field
CI_MD_SO_RSFLDAT MG Search Object Result Field Attribute
CI_MD_SRC_TYPE RF Source Type
CI_MD_SRC_TYPE_L RF Source Type Language
CI_MD_SVC MG MD Service
CI_MD_SVC_L MG MD Service Language
CI_MD_SVC_PRG MG MD Service Program
CI_MD_TAB_MOD MG UI Tab Module
CI_MD_TBL MG MD Table
CI_MD_TBL_FLD MG MD Table Field
CI_MD_TBL_FLD_L MG MD Table Field Language
CI_MD_TBL_L MG MD Table Language
CI_MD_TMPL RF Template
CI_MD_TMPL_ELTY RF Template Element Types
CI_MD_TMPL_L RF Template Language
CI_MD_TMPL_VAR RF Template Variable
CI_MD_TMPL_VAR_L RF Template Variable Language
CI_MD_VAR RF Variable
CI_MD_VAR_DTL RF Variable Detail
CI_MD_VAR_DTL_L RF Variable Detail Language
CI_MD_WRK_TBL MG Work Table
CI_MD_WRK_TBLFLD MG Work Table Field
CI_MD_WRK_TBL_L MG Work Table Language
CI_MSG MG Message
CI_MSG_CATEGORY MG Message Category
CI_MSG_CATEGORY_L MG Message Category Language
CI_MSG_L MG Message Language
CI_NAV_OPT MG Navigation Option
CI_NAV_OPT_CTXT MG Navigation Option Context
CI_NAV_OPT_L MG Navigation Option Language
CI_NAV_OPT_USG MG Navigation Option Usage
CI_PORTAL MG Portal Page
CI_PORTAL_L MG Portal Page Language
CI_PORTAL_ZONE MG Portal Zone
CI_SCR MG Script
CI_SCR_CRT MG Script Criteria
CI_SCR_CRT_GRP MG Script Criteria Group
CI_SCR_CRT_GRP_L MG Script Criteria Group Language
CI_SCR_DA MG Script Data Area
CI_SCR_FLD_MAP MG Script Field Mapping
CI_SCR_L MG Script Language
CI_SCR_PRMPT MG Script Prompt
CI_SCR_PRMPT_L MG Script Prompt Language
Oracle Utilities Application Framework Software Development Kit Developer's Guide 245
Table Name Upgrade Action Description
CI_SCR_STEP MG Script Step
CI_SCR_STEP_L MG Script Step Language
CI_SEQ MG Sequence
CI_TD_DRLKEY_TY MG To Do Type Drill Key
CI_TD_SRTKEY_TY MG To Do Type Sort Key
CI_TD_SRTKEY_TY_L MG To Do Type Sort Key Language
CI_TD_TYPE MG To Do Type
CI_TD_TYPE_L MG To Do Type Language
CI_XAI_ADAPTER MG XAI Adapter
CI_XAI_ADAPTER_L MG XAI Adapter Lang
CI_XAI_CLASS MG XAI Class
CI_XAI_CLASS_L MG XAI Class Language
CI_XAI_ENV_HNDL MG XAI Envelope Handler
CI_XAI_ENV_HNDL_L MG XAI Envelope Handler Language
CI_XAI_EXECUTER RF XAI Executer
CI_XAI_EXECUTER_L RF XAI Executer Language
CI_XAI_FORMAT RF XAI Format
CI_XAI_FORMAT_L RF XAI Format Language
CI_XAI_IN_SVC MG XAI Inbound Service
CI_XAI_IN_SVC_L MG XAI Inbound Service Language
CI_XAI_SVC_PARM MG XAI Inbound Service Parameters
CI_XAI_SVC_VERS MG XAI Inbound Service Version
CI_XAI_SVC_VERS_L MG XAI Inbound Service Version Language
CI_ZONE MG Zone
CI_ZONE_HDL MG Zone Type
CI_ZONE_HDL_L MG Zone Type Language
CI_ZONE_HDL_PRM MG Zone Type Parameters
CI_ZONE_HDL_PRM_L MG Zone Type Parameters Language
CI_ZONE_L MG Zone Language
CI_ZONE_PRM MG Zone Parameters
F1_BUS_OBJ MG Business Object
F1_BUS_OBJ_ALG MG Business Object Algorithm
F1_BUS_OBJ_L MG Business Object Language
F1_BUS_OBJ_OPT MG Business Object Option
F1_BUS_OBJ_STATUS MG Business Object Status
F1_BUS_OBJ_STATUS_ALG MG Business Object Status Algorithm
F1_BUS_OBJ_STATUS_L MG Business Object Status Language
F1_BUS_OBJ_STATUS_OPT MG Business Object Status Option
F1_BUS_OBJ_TR_RULE MG Business Object Transition Rule
F1_BUS_OBJ_TR_RULE_L MG Business Object Transition Rule Language
F1_BUS_SVC MG Business Service
F1_BUS_SVC_L MG Business Service Language
F1_DATA_AREA MG Data Area
F1_DATA_AREA_L MG Data Area Language
F1_MAP MG UI Map
F1_MAP_L MG UI Map Language
F1_SCHEMA MG Schema
Oracle Utilities Application Framework Software Development Kit Developer's Guide 246
Table Name Upgrade Action Description
SC_ACCESS_CNTL MG User Group Access Control
SC_APP_SERVICE MG Application Service
SC_APP_SERVICE_L MG Application Service Language
SC_USR_GRP_PROF MG User Group Profile
Key Generation
Key generation is performed for tables that have sequential or system generated prime key. This is performed automatically
for Java instances via the OUAF enTegrity.
Tables with a system-generated key contain their own unique key that is replicated in a related 'key table' suffixed with '_K'.
The purpose of the key table is to store the table identifier as well as the identifier of the environment in which the data row
exists. An example is the Account table containing the Account identifier and the Account Key table containing the Account
identifier and the Environment identifier.
These key tables support the Archiving and ConfigLab functionality by ensuring that a key will be unique across
environments.
Note: Oracle recommends that customers using Oracle Utilities Application Framework version 4.2 or later and
currently using ConfigLab switch to Configuration Migration Assistant (CMA) for their configuration data migration
needs and retain ConfigLab for migration of master and transaction data migration. Also note that CMA functionality
is not available to every Framework-based product. For details, including tips and requirements for moving from
ConfigLab to CMA for configuration data migrations, see the "Configuration Migration Assistant" section in the
Oracle Utilities Application Framework Aministration Guide.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 247
Example Table Metadata Key Information
In the Service Agreement table metadata example above, the metadata key information is shown by the values in the fields
Key Table, Type of Key and Inherited Key Prefix Length.
The primary key constraint is used to retrieve the name of the key field for the table from the field metadata.
The field metadata provides the field data type and length.
Note: Key Types. Although there are more types of keys indicated in metadata drop-down list, the only types
currently supported by the key generator in the Oracle Utilities Application Framework are system-generated and
sequential.
Note: Special Annotation. If a table's inherited key prefix length is non-zero, a special entry
"clusteringParentProperty" must be in the business entity annotation for this table.
Note: If you have run this process previously, old Source Code XML files will still be present. Previous information is
NOT deleted.
Open a Command Prompt window and run the script buildAppViewerSrcXML.bat. This script is available in SDK
shortcuts folder. e.g. C:\SPLSDK\SDK\shortcuts.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 248
This will prompt you for the location of the Source Code Folder, the location of the Destination Folder and the location of
the "desc.wrk" file.
Enter the FULL path name to the folder where the source code resides (quotes are not required). Source in this location will
be processed to build the required XML files. The process does NOT drill down through different levels of folders; only the
folder specified is examined. For example:
C:\spl\<CCB_INSTALLATION>\cobol\source\cm
Enter the FULL path name to the folder where the information is to be built (quotes are not required). These folders need to
exist before the script is run. Script will not create the folders. For example:
C:\temp\appViewerData
Enter the FULL path name to the location of the "desc.wrk" file. This is normally found in the Application Viewer under /
data/source. This file can be copied locally or used from the Application Viewer location (it is not updated). For example:
C:\spl\<CCB_INSTALLATION>\splapp\applications\appViewer\data\source
The process will then run automatically displaying each source file being processed.
Each source file is processed twice. This first pass extracts a program description from the source file. This should be a
quick process as the file is only examined until a description is located. The second pass reads the entire source file and
builds the XML file. This process also accesses the current database to check the meta-data for tables used by SQLs within
the source.
When the process is complete, the extension information will be present under the destination folder you specified. The
structure under the destination will mirror the structure under the data/source/ folder of the Application Viewer (only the
CM folder is created). Move the XML files from the CM folder to the corresponding CM folder under the Application
Viewer. The information is immediately available.
e.g. if the destination directory is c:\temp\appViewerData then the processed data is available at c:\temp\appViewerData
\source\CM. Copy the contents under c:\temp\appViewerData\source\CM to Application Viewer folder C:\spl\<CCB_
INSTALLATION>\splapp\applications\appViewer\data\source\CM.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 249
private final ConcurrentMap<AlgorithmType_Id, AlgorithmTypeInfo> algorithmTypeInfoById =
new ConcurrentHashMap<AlgorithmType_Id, AlgorithmTypeInfo>();
protected AlgorithmTypeInfoCache() { ContextHolder.getContext().registerCache(this); }
public String getName() { return "AlgorithmTypeInfoCache"; }
public void flush() {algorithmTypeInfoById.clear(); }
public static AlgorithmTypeInfo getAlgorithmTypeInfo(AlgorithmType_Id algTypeId) {
return INSTANCE.privateGetAlgorithmTypeInfo(algTypeId);
}
DO: it is safe to use XML documents (to be consumed by BOs, BSs, or SSs) for moving data between sessions.
Every entity has a unique corresponding "id" class, e.g. BatchControl has BachControlId. The ORM framework
automatically generates correct SQL to perform the following essential tasks:
Read, update, insert, delete one entity (row) from the database.
Navigate between related entities as per their key/constraint relationships, for example from a parent entity to a collection
of children.
In the above example, the getEntity() call only retrieves the parent ID as a proxy. The "someBatchControl" is not fully
"hydrated" until some other property is accessed. "Hydrating Entities" is the process of taking a row from the database and
turning it into an entity.
The getParameters() call only retrives the child IDs, again as proxies.
Only when the getBatchParameterName() is called, is a row (the child row) actually retrieved.
ID Objects
When you create an ID, the ID object will not be null. After you use an ID to retrieve an entity (using getEntity()), that is
when you find out if the entity actually exists. Just because an ID exists, doesn't mean the entity itself exists! DO: So you
must check for null before attempting to use the entity you retrieved. For example:
BatchControlId id = ...
BatchControl batchControl = id.getEntity();
if (batchControl == null) { /* oh oh */ }
Oracle Utilities Application Framework Software Development Kit Developer's Guide 250
Counting a collection
DO: If you want to count the number of batch control parameters that belong to a parent batch control, use the size() method
as in the following example:
The framework implementation code has an optimized implementation of the size() method, which either counts the
existing in-memory collection elements, if they are already present, or issues a SQL count(*) query, if they aren't.
if(query.listSize() > 0) {
while (iter.next()) { .... }
}
The call to listSize() will make an unnecessary call to "select count(*)". Let the iterator do the work. Avoid the extra call to
the database.
DO: Use this instead - it'll use the cache and will almost certainly be faster:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 251
Write code using navigation first, then ADD the fetch query later, only if it's needed.
This is a link to the Hibernate help on "fetch": http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/
#performance-fetching
Session Cache
If an entity is retrieved previously within a session - in most cases - it does not have to be retrieved again since it is stored in
the session cache.
So, multiple BO reads against Java-backed MO's do not re-execute SQL.
The exception is when a call to COBOL is made. Since Java does not know what COBOL could have changed, the entities
must be refreshed from the database. Similary BO Reads against COBOL will always re-execute SQL.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 252
Prepared statement - use binding
DON'T: Never concatenate values - DO: use binding instead. Besides helping to reduce security concerns with SQL
injection, concatenation results in reparsing of SQL statements by the database. You could also lose the benefits of any
PreparedStatement caching by the jdbc drivers.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 253
If the maintenance object is written in COBOL, keep the plug-in algorithms in COBOL as well.
Batch Performance
Commit Considerations
DON'T: Do not commit too frequently. For example, we do not commit ever record since each commit has overhead at the
database; however, sessions with lots of objects in the cache should commit more frequently. Adjust your default value
accordingly.
<schema fwRel="2">
<mainSection type="group" mdField="C1_TAXFORM_MAIN_LBL"/>
<selectTaxFormLabel type="group" mdField="C1_SELECT_TAXFORM_LBL"/>
<taxFormId mapField="TAX_FORM_ID" isPrimeKey="true" fkRef="C1-TXFRM"/>
<formType mapField="FORM_TYPE_CD" fkRef="C1-FRMTY"/>
<bo mapField="BUS_OBJ_CD" fkRef="F1-BUSOB" suppress="true"/>
<boStatus mapField="BO_STATUS_CD"/>
<statusUpdateDateTime mapField="STATUS_UPD_DTTM" suppress="true"/>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 254
<totalAmountDueOverpaid mapField="C1_TOTAL_OWED_OVERPAID"/>
<remittanceAmount mapField="C1_FORM_PYMNT_AMT"/>
<formSource mapField="C1_FORM_SRCE_CD" fkRef="C1-FRMSC"/>
<formDetailsInfoSection type="group" mdField="C1_ITF_FORM_DTLS_INFO"/>
<demographicInfoSection type="group" mdField="C1_TF_DEMO_INFO_LBL"/>
<taxpayerDemographicInformation type="group">
<includeDA name="C1-TaxpayerDemoInfo"/>
</taxpayerDemographicInformation>
<lineItemsInfoSection type="group" mdField="C1_TF_LINE_ITEMS_LBL"/>
<obligationId mapField="SA_ID" fkRef="SA"/>
<receiveDate mapField="RECV_DT" required="true"/>
<taxFormFilingType mapField="TAX_FORM_FILING_TYPE_FLG" default="C1OR" required="true"/>
<formBatchHeaderId mapField="FORM_BATCH_HDR_ID" fkRef="C1-FBHDR"/>
<documentLocator mapField="DOC_LOC_NBR"/>
<adjustReason dataType="lookup" mdField="C1_TXF_ADJRSN_FLG" mapXML="BO_DATA_AREA"/>
<transferReason dataType="lookup" mdField="C1_TXF_TFRRSN_FLG" mapXML="BO_DATA_AREA"/>
<reverseReason dataType="lookup" mdField="C1_TXF_RVSRSN_FLG" mapXML="BO_DATA_AREA"/>
<cancelReason dataType="lookup" mdField="C1_TXF_CANRSN_FLG" mapXML="BO_DATA_AREA"/>
<issuesSection type="group" mdField="C1_TF_ISSUES_LBL"/>
<suspenseIssueList type="group" mapXML="BO_DATA_AREA">
<includeDA name="C1-IssuesList"/>
</suspenseIssueList>
<waitingForInfoIssueList type="group" mapXML="BO_DATA_AREA">
<includeDA name="C1-IssuesList"/>
</waitingForInfoIssueList>
<taxpayerPersonID fkRef="PER" mdField="PER_ID" mapXML="BO_DATA_AREA"/>
<account fkRef="ACCT" mdField="ACCT_ID" mapXML="BO_DATA_AREA"/>
<taxRole fkRef="C1-TXRL" mdField="TAX_ROLE_ID" mapXML="BO_DATA_AREA"/>
<transferAdjustSection type="group" mdField="C1_TF_TRANSFER_ADJUST"/>
<adjustedFromForm fkRef="C1-TXFRM" mapXML="BO_DATA_AREA" mdField="C1_TF_ADJUSTED_FROM"/>
<transferredFromForm fkRef="C1-TXFRM" mapXML="BO_DATA_AREA" mdField="C1_TF_TRANSFERRED_
FROM"/>
<adjustedToForm fkRef="C1-TXFRM" mapXML="BO_DATA_AREA" mdField="C1_TF_ADJUSTED_TO"/>
<transferredToForm fkRef="C1-TXFRM" mapXML="BO_DATA_AREA" mdField="C1_TF_TRANSFERRED_TO"/>
<version mapField="VERSION" suppress="true"/>
</schema>
This performance-sensitive process only required a subset of the BO, so the following light BO was created:
<schema fwRel="2">
<taxFormId mapField="TAX_FORM_ID" isPrimeKey="true" fkRef="C1-TXFRM"/>
<formType mapField="FORM_TYPE_CD" fkRef="C1-FRMTY"/>
<bo mapField="BUS_OBJ_CD" fkRef="F1-BUSOB" suppress="true" required="true"/>
<boStatus mapField="BO_STATUS_CD"/>
<receiveDate mapField="RECV_DT"/>
<formChangeReasons type="group" mapXML="BO_DATA_AREA">
<formChangeReasonsList type="list">
<formChangeReason mdField="FORM_CHG_RSN_CD" isPrimeKey="true" fkRef="C1-FRCHR"/>
</formChangeReasonsList>
</formChangeReasons>
<formChangeComments mdField="COMMENTS" mapXML="BO_DATA_AREA"/>
<version mapField="VERSION" suppress="true"/>
</schema>
Oracle Utilities Application Framework Software Development Kit Developer's Guide 255
Disadvantage of Light BOs
While this is not really a disadvantage of the concept, creating additional BOs results in more objects to maintain.
Data Explorer
It is important to understand that Data Explorers process ALL records returned from the database, even if they are not
displayed. For example, FK ref info strings, BS calls, SS calls, Inhibit Row in Explorers - all can cause per-row processing
even if they are not displayed.
Data Explorers are rendered using JavaScript. They are not designed to display many records, and trying to do so will result
in possibly unacceptable performance. DO: Consider limiting the results returned and asking Users to add additional filter
criteria to narrow down the results. DON'T: Don't try to display hundreds of records.
Zone Configuration
DO: Consider limiting the number of rows retrieved by the database limiting the query size. Specify this on the zone
parameter and the query will use the "rownum" technique to restrict the number of rows returned.
DO: As a rule-of-thumb: 10 columns (even if not visible) in a data explorer zone should be an alert to really think about
performance implications.
DO: Try to perform all processing in the SQL instead of fkInfo, BS, or SS calls in other columns. As described earlier,
these would be additional processes run on a per-row basis. If a description exists, consider using the description and
a Navigation Option instead of the Foreign Key. For example, replace the Person fkRef with Person Name and its
Navigation Option.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 256
Secondary Unique Indexes
DO: Use a JOIN instead of EXISTS. This is faster for unique scan indexes.
DO: Use EXISTS instead of IN when working with ID fields, use '=' instead of LIKE. Using LIKE on a system-
generated key isn't "reasonable"
CONSIDER: Using functions like TO_DATE(), SUBSTR() etc. means indexes on those fields won't be used! Use only
when necessary.
DO: Use the power of optional filters - and not just in the WHERE clause.
Note that Table B is not necessary; you could instead simply link directly from A to C.
Offload tasks, like string manipulations, concatenations, row numbering, case conversions, type conversions etc., to the
front-end applications
Do basic validations in the front-end during data entry. This saves unnecessary network roundtrips.
Avoid using UNION - use UNION ALL if it is possible.
Operators <> and != will NOT use the index! Also the word "NOT" Use the Greater Than or Less Than operators.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 257
Diagnosing Performance Issues
Execution times can be obtained in a number of ways.
Fiddler
In a UI-oriented scenario, the first recommended analysis tool is to use an http logger like fiddler (http://www.fiddler2.com).
This tool should make it apparent if there are excessive calls from the client browser to the server and the server response
times as seen from the browser. The timings can then be categorized as server-side or client side calls. When using fidder be
sure to enable the following:
"Time-to-Last-Byte"
"Response Timestamp"
log4j.logger.com.splwg.base.api.service.ServiceDispatcher=debug
Basic Logging
The following code can be placed in a junit test to log execution times:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 258
Timing code ('shootout'):
The code below will run a BO Update 100 times and report the amount of time taken. Note the 5 "warmup" executions
before the repeated 100 runs.
// warmups
for (int i = 0; i < 5; i++) {
BusinessObjectDispatcher.execute(doc1,
BusinessObjectActionLookup.constants.FAST_UPDATE);
rollbackAndContinue();
BusinessObjectDispatcher.execute(doc2,
BusinessObjectActionLookup.constants.FAST_UPDATE);
rollbackAndContinue();
}
long totalElapsed = 0;
// speed
for (int i = 0; i < 100; i++) {
long start = System.nanoTime();
BusinessObjectDispatcher.execute(doc1,
BusinessObjectActionLookup.constants.FAST_UPDATE);
flush();
totalElapsed += System.nanoTime() - start;
rollbackAndContinue();
}
System.out.println("Script (100): " + totalElapsed / 1000000 + "ms");
totalElapsed = 0;
for (int i = 0; i < 100; i++) {
long start = System.nanoTime();
BusinessObjectDispatcher.execute(doc2,
BusinessObjectActionLookup.constants.FAST_UPDATE);
flush();
totalElapsed += System.nanoTime() - start;
rollbackAndContinue();
}
System.out.println("Java (100): " + totalElapsed / 1000000 + "ms");
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 259
@Override
public Void call() throws Exception {
function(x);
return null;
}
};
PerformanceTestCallable exprPerfCallable = new PerformanceTestCallable("Expression "
+ expression.getExpressionString(), exprCallable);
PerformanceTestCallable javaPerfCallable = new PerformanceTestCallable("Java",
javaCallable);
Each of the performance callables is treated the same. It gets a series of warmup executions, in order to populate caches, and
allow hotspot JVM optimizations of any methods. Then the accurate system nano timing (e.g., System.nanoTime()) is called
around the loop of the given number of reps.
Profiling
The code below uses YourKit's controll classes to create a snapshot.
// warmups
for (int i = 0; i < 5; i++) {
BusinessObjectDispatcher.execute(doc, BusinessObjectActionLookup.constants.FAST_
UPDATE);
rollbackAndContinue();
}
Oracle Utilities Application Framework Software Development Kit Developer's Guide 260
PerformanceTestHelper API
As before, the PerformanceTestHelper helps by providing a seamless interface into the yourkit profiler, for various options
of sampling, tracing, monitoring threads or timing in threads:
The PerformanceTestHelper utility class uses reflection to know whether the yourkit library is available or not. If it is
not available (such as on the build server), the behavior reverts to simple timing protocols of the corresponding callable
iterations. If it is available (such as on a developer's workstation, and they want to profile a test), then the yourkit profiler is
connected to. This would require actually running the test under a profile session, else an error is produced.
Profiling a callable is somewhat similar to the simple timing of a callable, except for some added steps:
1. Performs some warmups
2. Forces garbage collection via the yourkit API
3. Starts the given profile type (sample vs trace)- the test should be run without automatically starting the profiler
4. Wrap the repetition loop in a timer
5. Capture a snapshot
This design approach allows profile/performance tests to be checked into version control, for re-profiling at a later point,
and for documentation examples of how to profile code, etc.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 261
Chapter 4
Packaging Guide
Note: CM releases will correspond to a specific base product version and can only be installed on base product
environments of that version. Customers installing a CM release must first verify the corresponding base product
version with the Implementation team.
Note: This document describes CM packaging utilities operation for Oracle database only. The application server can
be Unix or Windows/DOS operating system. In Unix you must execute the script with .sh suffix, in window the script
with .cmd suffix. They both will execute the same Perl script with .plx suffix. For instance:
applyCM.sh: Unix driver script
applyCM.cmd: Windows driver script
applyCM.plx: Perl script
All the examples in this document are related to Unix. If you are in Windows/DOS simply execute the same scripts, but
using .cmd extension instead .sh.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 262
The starting point of packaging the app server component is the project repository. The tool extractCMSource is used to
get the source from the project repository into the packaging directory.
Note: The packaging directory must not be used for any other purpose except for storing the extracts. Mixing other
files into the packaging directory will result in errors in succeeding processes.
applyCM copies the extracted source to the packaging app server. It then does all the necessary steps like generate,
compile, etc., to update the packaging app server runtime based on the extracted source.
create_CM_Release is then used to create CM release install package from the packaging app server. The CM release
install package contains all CM code that has been applied to the packaging app server.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 263
The install tool applies the CM release install files to either QA or production app servers.
Note: Release install packages are usually applied only to fresh environments, e.g., to apply the first batch of CM
code or when upgrading to a new version of the product. To install additional code to an existing environment, patch
install packages (described next) are used.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 264
CM patch install packages are used to update an existing installation with the changes since it was last updated. A patch
install package is created by create_CM_Patch as the difference between two CM release install packages (a newer one
and an older one), e.g., for a monthly update schedule, CM release install packages are created every month and every
month, a cm patch install package is created using the release install packages from the previous and the current month.
To create a patch install package, a new release install package must be created first. Note that a release (not patch) install
package must be available for the previous period. Executing create_CM_Patch with the two CM release install packages as
input creates the patch install package.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 265
Developing Off-site
When developing off-site, there may be no available environments on the target platform. In this case, development and QA
must be done off-site, but packaging and QA must be re-done on-site using environments on the target platform.
Off-site Process
Development and QA (and the packaging) is done using the same procedure as on-site except for the following:
Packaging and QA are done on environments that may not match the target platform.
Instead of sending a release or patch install package to the implementation site, only the source from the install package
is sent. This package is called the release/patch source package. It is created by executing extractCMSource with the
data directory of the install package as the source directory.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 266
Off-site Development Release
On-site Process
Upon receiving the release/patch source package, the on-site team proceeds with the regular packaging procedure starting
from the applyCM step using the release/patch source package as the source directory.
On-site Packaging
Guidelines
Applying a CM patch install package to QA or production app servers is the same as for release install package, e.g., it is
done simply by executing the install tool from the the package directory. By using these scripts, implementation developers
can prepare an installation package containing the contents of their custom modifications. Developers need to build a
packaging environment on a server of the same operating system platform as used by the target environment to create
CM release packages. A version number must be used to identify each custom modifications (CM) release version. Once
developers select a version number format, the version number must be stored on the environment in the file $SPLEBASE/
etc/CMVERSION.txt, to achieve this place CMVERSION.txt file in etc subdirectory in your patch directory.
Implementers are strongly recommended to use CM packaging utilities for implementation delivery to customer site. It will
ensure the correct installation complying with base product rules and will keep an environment upgradable. Please, note,
that web files can be also packaged in archive war format (if $isExpanded environment variable is set to false), in that case
it is not possible to just manually copy changes to the directories.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 267
App Server CM Packaging Tools
The following utilities are provided in this package for maintaining the packaging environment and creating release versions
of customer modifications (CM):
extractCMSource utility, used to extract source from an app server or from a release or patch install package.
applyCM utility, used to apply a CM patch to a packaging environment.
create_CM_Release utility, used to create a full CM release version.
create_CM_Patch utility, used to create CM patch release version utility.
Instructions for using these utilities are described in the following sections.
Display Usage
To display the usage information, just execute the utility without any parameters from the Windows command prompt.
perl extractCMSource.plx
Oracle Utilities Application Framework Software Development Kit Developer's Guide 268
Extract From an App Server
To extract the source from a development app server, specify the app server directory as the source directory. For example,
the following invocation extracts source from an app server named CM_PROJ1 in the C:\SPL directory into C:\CMExtarct
and marks the extract as version CM1.0:
Oracle Utilities Application Framework Software Development Kit Developer's Guide 269
to be executed using the full pathname (this is necessary because you need to be located in a different folder, see below). In
addition, you need to be set to a target environment (e.g. packaging environment).
Script: <CM scripts>/applyCM.sh
Usage:
(no options)
Apply patch on top of the existing base product and possibly CM integration environment. This mode will add new CM
files from patch to the environment and replace the changed ones. But it will not delete the previously existing in the
environment CM modules that are not part of the patch.
It needs to be executed from the source root folder.
-d
Remove all previous CM modules from the environment and apply patch on clean base product environment. This option is
useful when needed to create the CM integration environment from scratch.
It needs to be executed from the source root folder.
-b
Recompile the existing sources in current environemnt. Usually it is used to execute full recompile a development
environment.
It needs to be executed from the application folder root, e.g. $SPLEBASE.
-n
It won't stop/start automatically the target environment.
The input for applyCM.sh utility is current folder (source root folder), which contains the following subfolders:
java
scripts
etc
services
splapp
These subdirectories contain only CM modules created according to the rules of the document "Naming conventions for
tailoring application implemetation" (see Installation Guide of the product). This directory structure should be prepared and
filled with relevant CM modules on development Windows server, then copied over to the server that hosts a packaging
environment by ftp utility. After that you can apply the patch to the packaging environment. Modules that are not created
using these conventions will be ignored by applyCM.sh utility. You have to reside in the patch directory to apply
the patch. ApplyCM utility will generate and compile java code, will create java jar file (cm.jar) required for customer
implementation platform.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 270
It is mandatory that every implementation version is identified by its own release version number. This number may be
in any free standard and must be recorded in the $SPLEBASE/etc/CMVERSION.txt file on the environment.
Here are the detailed instructions for creating the full release version for CMs:
Log in to the server with the administrator user id and initialize a packaging environment. You will use this environment
to create the CM release version.
Change the directory to the directory that contains the Developers Tool Suite utilities (CM_packaging).
Execute the utility using the following command:
./create_CM_Release.sh -e $SPLENVIRON -v $VERNO -d $RELEASEHOME,
where
$SPLENVIRON is the target packaging environment
$VERNO is the CM version number (the content of the file CMVERSION.txt)
$RELEASEHOME is the name of the directory on the server where you want to place the resulting CM release
package.
For example:
./create_CM_Release.sh -e M4_Q1_SUNDB2 -v M.4.0.0 -d /versions
Tar and zip the resulting CM release directory for Unix platform or zip it for Windows platform and ship it to your
customer.
The customer who wishes to install the delivered package onsite will follow the instructions:
Decompress and untar the installation media to a temporary directory for the Unix server or unzip it for Windows server.
Change directory to the target directory.
Login and initialize the target environment.
Change to the Installation directory using the following command
cd CMCCB.$VERNO
where
$VERNO is the version number (the content of the file CMVERSION.txt)
Run the following script
./install.sh - for Unix
install.cmd - for Windows
Fastpath: Before executing the utility, be sure that both packages are available in the same directory on the server.
During the installation process at the customer site, the patch install utility will not remove the previous version of CM
modules, and will only install the patch content on top of the previous CM version.
Here is the process for creating a patch release CM version:
Log in to the server with the administrator user id.
Change directory to the name of the directory that contains the SDK packaging utilities (CM_packaging).
Oracle Utilities Application Framework Software Development Kit Developer's Guide 271
Execute the utility by entering the following command:
./create_CM_Patch.sh -d $RELEASEHOME
where:
$RELEASEHOME is the directory that currently holds your CM full release packages - and where you also want to put
your new patch package.
Tar and zip the resulting CM patch directory for Unix platform or zip it for Windows platform and ship it to your customer.
The customer who wishes to install the delivered package onsite will follow the instructions:
Decompress and untar the installation media (on Unix) or unzip (on Windows) to a temporary directory.
Change directory to that directory.
Login and initialize the target environment.
Change to the Installation directory by using the following command
cd CMCCB.$VERNO
where
$VERNO is the version number (the content of the file CMVERSION.txt)
Run the following script
./install.sh - on Unix
install.cmd - on Windows
Oracle Utilities Application Framework Software Development Kit Developer's Guide 272
Packaging CM system data starts by creating a copy of the project dev database into a project release database. A
blueprint file of the system data is then created by executing the OraSDBP tool.
To apply the latest changes to a QA or production database, execute OraSDUp with the blueprint file as input and then
specifying the target database.
Extract Process
Extract process involves extracting CM system data based on the rules defined in a parameter file and packaging it in a
binary file - blueprint. This file can then be used as an input source by the data upload process.
The following example uses the Oracle database platform to illustrate the extract and upload process.
OraSdBp.exe, included in this package, is the extract utility that reads an input parameter file for the list of Oracle database
tables, extracts data from these tables and compresses into a binary file (blueprint).
A sample extract parameter file extract_cmsystbls.lst is included in this package to provide the implementers a starting
point. This parameter file, as can be seen, defines rules for the tool to extract CM data based on their key definition.
However, in some cases, CM data may be stored on 'CI' rows. The column user_exit_pgm on CI_MD_PRG_COM table
is one such case. For cases like these, the implementers can choose to change the extraction rules in this file to match their
requirements.
To extract your data, make a copy of extract_cmsystbls.lst file and edit it to match your requirements. Execute the extract
process from a Command-window and provide it with the required parameter when prompted.
The data in input parameter must match the following format:
CI_ALG_TYPE_L;LANGUAGE_CD = 'ENG';VERSION
Where, the first field stores the table name, second field stores the selection criteria (where clause for selecting data) and the
third field stores the list of column that should be ignored during extraction. The character semi-colon is used as the field
Oracle Utilities Application Framework Software Development Kit Developer's Guide 273
separator. If there are multiple columns that need to be ignored (not included in the data being extracted), comma can be
used in the third field as the separator.
OraSdBp accepts the following parameters:
-d Connect String
Where the Connect String contains:
Schema owner name (say CISADM)
Password for schema owner.
Database name.
This is a mandatory parameter. If not entered, the utility will prompt the user to build the connect string.
Connect String should be entered in the following format:
CISADM,CISADMPSWD,DBNAME
(Comma-separated and no space).
-i Input Parameter file name.
Name of the input parameter file that the utility reads to get the list of tables and their selection criteria. This parameter is
optional. The default input parameter file name is CDXSdBp.Inp.
-o Output File Name.
This is the name of the binary file that the utility creates. This parameter is optional. The default output file name is
"OraSdBp" (without extension).
-c NLS characterset of the target database
The utility uses this parameter to set the NLS_LANG parameter on the client side. This parameter is then validated
against the character set of the source database and is saved in the blueprint. This is mandatory parameter and is
prompted for if not set by the user.
-h Help.
This option will list all the accepted parameters with a brief description.
Upload Process
Data upload process compares the data included in the blueprint file (generated by the extract process) and that extracted
from a target database and generates output SQL to synchronize them.
The utility OraSdUpg, included in this package, is used by the process utility to compare and synchronize the data in the
target database with that in the input blueprint file.
OraSdUpg reads an input parameter file for the list of the tables to be upgraded along with the selection criteria and upgrade
rules for each table.
Each table has a corresponding record in the file with following 6 fields separated by semi-colon:
Table Name
The instance of the table. This number should be always set to 1. The cases where more than one instances of a table are
processed are extremely rare and are not discussed here.
Selection Criteria for the table.
Insert allowed indicator (T/F): Whether records should be inserted into the target database table if they missing in the
database but exist in the binary file.
Update allowed indicator (T/F): Whether records should be updated in the table if they have different values than in the
binary file.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 274
Delete allowed indicator (T/F): Whether the obsolete data in table in the target database. Obsolete records exist in target
database but not in the binary file.
Fresh Install Indicator (T/F): Whether the table should be seeded during the very first install. This indicator is only used
when the utility is invoked with "-f" switch.
List of columns not updated can be specified in the sixth field. Use a comma to separate the column names if multiple
columns are to be ignored during updates. These columns will be inserted but will not be updated during the data
synchronization process.
Following is the example of how these records should look like in the file:
CI_LOOKUP;1;LANGUAGE_CD = 'ENG';T;T;F;T;DESCR
A sample file upload_cmsystbls.lst has been included in this package. Implementer can make a copy of this file and edit it to
match their requirements.
Before making connection to the target database, the utility reads the header from the blueprint and sets NLS_LANG
environment variable on the client machine. It then validates this character set setting to the character set of the target db
after making a connection and warns user if there is a mismatch.
The utility can be executed in verification and modification modes. In verification modes, the action SQL statements are
simply written to the log file but in modification mode they are applied the target database.
It is very important to note that the primary requirement for OraSdUpg is definition (column and primary key) of tables
being upgrade in the target database should be same as that in the database from which the binary file was extracted.
Be careful while selecting the table and the selection criteria because to compare the data, the utility, for each table, first
loads the data from the binary file and the database in the memory. If a table has huge amount of data and selection criteria
set causes the utility to work on large quantity of data, it may run out of memory.
To avert unique key constraint violation error that can be caused by improper sequence of data deletion and insertion on
a table and also the foreign key issues, the utility first gathers all the generated action statements for all the tables before
executing them. The execution of all the generated statements is done in multiple iterations. After each iteration, all the
failed statements during that iteration are collected and executed again in the next iteration. The iterations are repeated till
either all the statements in iteration are executed successfully or they fail.
The utility disables and enables all the triggers on the tables being upgraded before and after applying database changes. No
triggers get executed during the system data upgrade.
OraSdUpg accepts the following parameters:
-d Connect String
Where the Connect String contains:
Schema owner name (say CISADM)
Password for schema owner.
Database name.
This is a mandatory parameter. If not entered, the utility will prompt the user to build the connect string.
Connect String should be entered in the following format:
CISADM,CISADMPSWD,DBNAME
(Comma-separated and no space).
-b Bypass the database character set validation.
Before upgrading data in database, the utility validates character set stored in the blueprint by OraSDBp against that of
target database. The user can bypass this validation step by setting this switch.
-p Input Parameter file name.
Name of the input parameter file that the utility reads to get the list of tables and their selection criteria. This parameter is
mandatory.
-i Input Binary File.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 275
This is the name of the binary file that the utility reads to extract the data that it then uses to upgrade the target database.
This is a mandatory parameter.
-f
Treats the data synchronize process as New install. When set, the flag forces OraSdUpg to use "fresh install indicator"
for the tables where INSERT indicator is set to false and compels it to insert missing records in all of them. Optional.
-u
Makes OraSdUpg run in the modification mode. Optional.
-l Log File Name.
This is the name of the file that OraSdUpg creates, if it is missing and starts appending the information about the action it
is performing.
-h Help.
This option will list all the accepted parameters with a brief description.
Note: It is recommend that the implementers execute the upload process first in the verification mode and review the
SQL before running the tool in the modification mode.
Oracle Utilities Application Framework Software Development Kit Developer's Guide 276