08 PRGM Customizing

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 40

8

Programmatically Customizing Data Services

Copyright © 2008, Oracle. All rights reserved.


Objectives

After completing this lesson, you should be able to do the


following:
• Generate Java classes for business components
• Override class methods
• Implement programmatic modifications
• Add service methods to an application module
• Create a test client
• Use business component client APIs

8-2 Copyright © 2008, Oracle. All rights reserved.


Generating Java Classes for Adding Code

To generate a Java class:


1. On the business component editor’s Java page, click Edit
2. Select classes to generate

8-3 Copyright © 2008, Oracle. All rights reserved.


Programmatically Modifying the Default
Behavior of Entity Objects

Many modifications are possible with coding, such as:


• Traversing associations
• Overriding base class methods

8-4 Copyright © 2008, Oracle. All rights reserved.


The Supporting Entity Java Classes

• EntityImpl
– The entity class
– Represents a row
– Provides getter and
setter methods
• EntityDefImpl
– The entity definition class
– Represents the whole entity
– Can be used to modify the entity definition
• EntityCollImpl
– Represents the cached set of rows from the entity
– Not usually necessary to modify or override methods in this
class

8-5 Copyright © 2008, Oracle. All rights reserved.


Traversing Associations

PersonEOToOrderEO OrderEO
PersonEO
getPersonEO()
getOrderEO() setPersonEO()
getEmail() getPersonEmail()
Accessor in source Accessors in destination
to get destination to get and set source

• The destination entity’s EntityImpl.java file contains


methods to get and set the source entity. For example,
OrderEOImpl.java contains getPersonEO() and
setPersonEO().
• You could add a method to OrderEO.java to get the
email address of the associated person (customer):

public String getPersonEmail() {


return getPersonEO().getEmail(); }

8-7 Copyright © 2008, Oracle. All rights reserved.


Overriding Base Class Methods

You can override methods in


the base classes for objects.
For example, you can override
methods in EntityImpl.java,
such as:
• doDML(): Use it to log
changes in another entity.
• beforeCommit(): Use it to
validate multiple instances of the
same entity.
• remove(): Use it to log a
deletion in an entity.

8-8 Copyright © 2008, Oracle. All rights reserved.


Overriding Base Class Methods Example:
Updating a Deleted Flag
Instead of Deleting Rows

// In <Entity name>Impl.java

1 public void remove() {


setDeleted("Y");
super.remove();
}

2 protected void doDML(int operation,


TransactionEvent e) {
if (operation == DML_DELETE) {
operation = DML_UPDATE;
}
super.doDML(operation, e);
}

Overriding the remove() and doDML() methods

8-9 Copyright © 2008, Oracle. All rights reserved.


Overriding Base Class Methods Example:
Eagerly Assigning Values
from a Database Sequence

// In ProductEOImpl.java
import oracle.jbo.server.SequenceImpl;
// Default ProdId value from PRODUCTS_SEQ sequence at
1 protected void initDefaults() {
2 super.initDefaults();
SequenceImpl sequence = new
3 SequenceImpl("PRODUCTS_SEQ",getDBTransaction());
DBSequence dbseq = new
4
DBSequence(seq.getSequenceNumber());
5 populateAttributeAsChanged(ProdId, dbseq);
}

Overriding the initDefaults() method

8 - 10 Copyright © 2008, Oracle. All rights reserved.


Programmatically Modifying the Default
Behavior of View Objects

For example, you can:


• Change the WHERE or ORDER_BY clause programmatically
• Retain and reuse a row set
• Traverse view links

8 - 11 Copyright © 2008, Oracle. All rights reserved.


The Supporting View Object Java Classes

• ViewObjectImpl
– The view class
– Provides methods
to manage the row
set
• ViewDefImpl
– The view definition class
– Represents the whole view
– Can be used to modify the view definition
• ViewRowImpl
– The view object row class
– Instantiated for each record returned by the query
– Provides attribute accessors

8 - 12 Copyright © 2008, Oracle. All rights reserved.


Examining View Object Methods

Javadoc for the


ViewObjectImpl class

8 - 13 Copyright © 2008, Oracle. All rights reserved.


Changing View Object
WHERE or ORDER BY Clause at Run Time
Database
Table
CustomerStatusRO
Name Status
ID NAME STATUS select name, Mike Silver
201 Susan Platinum status
Steve Gold
202 Mike Silver from customers
201 Steve Gold order by name Susan Platinum

ViewObject vo = am.findViewObject Name Status


("CustomerStatusRO");
String whereClause = "NAME < 'Su'"; Steve Gold
Mike Silver
String orderByClause = "STATUS";
vo.setWhereClause(whereClause);
vo.setOrderBy(orderByClause);

8 - 16 Copyright © 2008, Oracle. All rights reserved.


Using Named Bind Variables at Run Time

Assigning values to named bind variables at run time:


ViewObject
ViewObject vo
vo == am.findViewObject("PersonView1");
am.findViewObject("PersonView1");
vo.setNamedWhereClauseParam("TheName","alex%");
vo.setNamedWhereClauseParam("TheName","alex%");
vo.executeQuery();
vo.executeQuery();

Adding named bind variables at run time:


vo.setWhereClause("person_type_code
vo.setWhereClause("person_type_code == :PersonType");
:PersonType");
vo.defineNamedWhereClauseParam("PersonType",
vo.defineNamedWhereClauseParam("PersonType", null,
null, null);
null);
vo.setNamedWhereClauseParam("PersonType","STAFF");
vo.setNamedWhereClauseParam("PersonType","STAFF");
//
// execute
execute the
the query,
query, process
process the
the results,
results, and
and then
then later...
later...
vo.setNamedWhereClauseParam("PersonType","CUST");
vo.setNamedWhereClauseParam("PersonType","CUST");
//
// execute
execute the
the query,
query, process
process the
the results
results

8 - 18 Copyright © 2008, Oracle. All rights reserved.


Programmatically Retaining
and Reusing a View Link Accessor Row Set

To retain and reuse a view link accessor row set


programmatically:
1. Generate a Java class for the source view object.
2. Override the create() method.
3. Add setViewLinkAccessorRetained(true).
public
public class
class OrderVOImpl
OrderVOImpl extends
extends ViewObjectImpl
ViewObjectImpl {{
public
public OrdersViewImpl()
OrdersViewImpl() {{
}}
@Override
@Override
protected
protected void
void create()
create() {{
super.create();
super.create();
setViewLinkAccessorRetained(true);
setViewLinkAccessorRetained(true);
}}
}}

4. Call reset() each time you reuse the RowSet object.


8 - 19 Copyright © 2008, Oracle. All rights reserved.
Traversing Links

• Links may be traversed in either direction.


• ViewRowImpl.java contains a method to get the
associated row iterator.
• For example, OrdersViewRowImpl contains the method:
public
public oracle.jbo.RowIterator
oracle.jbo.RowIterator getOrderItemsView
getOrderItemsView ()
()

• Use the methods of RowIterator to move from row to


row and to get individual attribute values.

8 - 20 Copyright © 2008, Oracle. All rights reserved.


Application Module Files

• Created by default:
– <AppMod>AM.xml: Includes detailed metadata about the
View Objects included
– bc4j.xcfg: Contains all the configuration and connection
details
• Supporting Java classes:
– <AppMod>AMImpl.java: Contains all the methods and
behaviors that affect each application module instance
– <AppMod>AMDef.java: Contains methods to be used by
all instances of the application module

8 - 22 Copyright © 2008, Oracle. All rights reserved.


Centralizing Implementation Details

Best practice is to place code in application module service


methods rather than in multiple clients.

X Code to
manipulate
view objects

Client Application Module

8 - 23 Copyright © 2008, Oracle. All rights reserved.


Adding Service Methods
to an Application Module
Service methods:
• Are useful for:
– Code that is not dependent on a specific view
– Performing operations across view object instances
– Managing transactions
– Dynamically changing the data model
• Can be called from the client, requiring very little data
manipulation in the client itself
• Are implemented in the application module’s class
• Are added by:
– Adding code to the Java class
– Publishing to the client interface

8 - 25 Copyright © 2008, Oracle. All rights reserved.


Coding the Service Method

Add the Java code for the method to the


<AM_Name>AMImpl.java file.

8 - 27 Copyright © 2008, Oracle. All rights reserved.


Publishing the Service Method

To publish the service method to clients:


1. Open the Application
Module Editor and
select the Java panel
2. Click the Pencil icon
to edit the Client
Interface
3. Shuttle the method
you want to publish
into the Selected list

8 - 28 Copyright © 2008, Oracle. All rights reserved.


Testing Service Methods in the Business
Components Browser

Show the AM.

Select the method.


Set parameter values.

Click Execute.
Observe results.

8 - 30 Copyright © 2008, Oracle. All rights reserved.


Accessing a Transaction

• Transaction and DBTransaction are interfaces that


define database transactions.
• Use the methods in these interfaces to access an
application module’s transaction. For example:
ApplicationModuleImpl
ApplicationModuleImpl am;
am; ...
...
//
// Commit
Commit the
the transaction
transaction
am.getTransaction().commit();
am.getTransaction().commit();

8 - 31 Copyright © 2008, Oracle. All rights reserved.


Committing Transactions

Post phase

1. Validate pending changes.


2. Post updates to the database.

Commit phase

Commit the transaction.

8 - 33 Copyright © 2008, Oracle. All rights reserved.


Customizing the Post Phase

• Override the entity object’s postChanges() method.


• Example: For a deleted entity, mark the database row
instead of deleting the data.

public
public void
void postChanges(TransactionEvent
postChanges(TransactionEvent e)e) {{
if
if (getPostState()
(getPostState() ==== Entity.STATUS_DELETED)
Entity.STATUS_DELETED) {{
//
// Custom
Custom code
code to
to mark
mark database
database rows,
rows, such
such as
as
//
// by
by updating
updating aa Deleted
Deleted flag
flag in
in the
the record
record
}}
else
else {{
super.postChanges(e);
super.postChanges(e);
}}
}}

8 - 34 Copyright © 2008, Oracle. All rights reserved.


Customizing the Commit Phase

• Implement a TransactionListener.
• Implement beforeCommit() and afterCommit().
• Add your listener to the transaction’s list of
event subscribers.
• Alternatively, override the entity object’s
beforeCommit() or afterCommit() methods.
Example: In PersonEOImpl, print notification that record is committed:
@Override
@Override
public
public void
void afterCommit(TransactionEvent
afterCommit(TransactionEvent transactionEvent)
transactionEvent) {{
System.out.println("Record
System.out.println("Record committed
committed for
for "" ++
getFirstName()
getFirstName() ++ "" "" ++ getLastName());
getLastName());
super.afterCommit(transactionEvent);
super.afterCommit(transactionEvent);
}}

8 - 35 Copyright © 2008, Oracle. All rights reserved.


Using Entity Objects and Associations
Programmatically

• Code to manipulate an entity object is typically placed in


an application module class or the class of another entity
object.
• Typical tasks that you may need to code:
– Finding an entity object by primary key
– Updating or removing an existing entity row
– Creating a new entity row

8 - 36 Copyright © 2008, Oracle. All rights reserved.


Finding an Entity Object
by Primary Key

public
public String
String findOrderID(long
findOrderID(long orderId)
orderId) {{
String
String entityName
entityName == "oracle.fod.storefront.model.entity.OrderEO";
"oracle.fod.storefront.model.entity.OrderEO";
1 EntityDefImpl
EntityDefImpl orderDef
orderDef == EntityDefImpl.findDefObject(entityName);
EntityDefImpl.findDefObject(entityName);

2 Key
Key orderKey
orderKey == new
new Key(new
Key(new Object[]{orderId});
Object[]{orderId});

3 EntityImpl
EntityImpl order
order == orderDef.findByPrimaryKey(getDBTransaction(),
orderDef.findByPrimaryKey(getDBTransaction(),
orderKey);
orderKey);
4 if
if (order
(order !=
!= null)
null) {{
return
return (String)order.getAttribute(“ShipToName");
(String)order.getAttribute(“ShipToName"); }}
else
else {{ return
return null;
null; }} }}

8 - 37 Copyright © 2008, Oracle. All rights reserved.


Updating or Removing
an Existing Entity Row

public
public void
void updateEmpEmail(long
updateEmpEmail(long empId,
empId, String
String newEmail)
newEmail) {{
1 EntityImpl
EntityImpl emp
emp == retrieveEmployeeById(empId);
retrieveEmployeeById(empId);
if
if (emp
(emp !=
!= null)
null) {{
2 emp.setAttribute(“Email",newEmail);
emp.setAttribute(“Email",newEmail);
try
try {{
3 getDBTransaction().commit();
getDBTransaction().commit(); }}
catch
catch (JboException
(JboException ex)ex) {{
getDBTransaction().rollback();
getDBTransaction().rollback();
throw
throw ex;
ex; }} }} }}

8 - 38 Copyright © 2008, Oracle. All rights reserved.


Creating a New Entity Row

public
public long
long createProduct(String
createProduct(String name,
name, String
String description)
description) {{
String
String entityName
entityName == “oracle.
“oracle. fod.storefront.
fod.storefront. model.entity.ProductEO";
model.entity.ProductEO";
1 EntityDefImpl
EntityDefImpl productDef
productDef == EntityDefImpl.findDefObject(entityName);
EntityDefImpl.findDefObject(entityName);

2 EntityImpl
EntityImpl newProduct
newProduct ==
productDef.createInstance2(getDBTransaction(),null);
productDef.createInstance2(getDBTransaction(),null);
newProduct.setAttribute("Name",name);
3 newProduct.setAttribute("Name",name);
newProduct.setAttribute("Description",description);
newProduct.setAttribute("Description",description);
try
try {{
4 getDBTransaction().commit();
getDBTransaction().commit(); }}
catch
catch (JboException
(JboException ex)
ex) {{
throw
throw ex;
ex; }}
5 DBSequence
DBSequence newIdAssigned
newIdAssigned ==
(DBSequence)newProduct.getAttribute("ProdId");
(DBSequence)newProduct.getAttribute("ProdId");
return
return newIdAssigned.getSequenceNumber().longValue();
newIdAssigned.getSequenceNumber().longValue();

8 - 39 Copyright © 2008, Oracle. All rights reserved.


Using Client APIs

Client interfaces in the oracle.jbo package include:


• ApplicationModule
• ViewObject
• Row
(But NOT Entity)

8 - 41 Copyright © 2008, Oracle. All rights reserved.


Creating a Test Client

[Ctrl]+[Enter]

Need to modify names in


generated skeleton code
to reflect your AM
package and name and
VO instance name.

8 - 42 Copyright © 2008, Oracle. All rights reserved.


Using View Objects in Client Code

Examples of using view objects programmatically:


• Using query results programmatically
• Using view criteria to alter view object queries at run time
• Iterating master–detail hierarchy
• Finding a row and updating a foreign key value
• Creating a new row

8 - 43 Copyright © 2008, Oracle. All rights reserved.


Using Query Results Programmatically

ViewObject
setWhereClause
Row RowSet setNamedWhereClauseParam setNamedWhereClauseParam
Row executeQuery executeQuery
Row
hasNext hasNext hasNext
RowSetIterator
next next next

8 - 44 Copyright © 2008, Oracle. All rights reserved.


Using View Criteria Programmatically

ViewCriteria
ViewCriteria vc
vc == custOrdVO.createViewCriteria();
custOrdVO.createViewCriteria(); 1

ViewCriteriaRow
ViewCriteriaRow promotionRow
promotionRow == vc.createViewCriteriaRow();
vc.createViewCriteriaRow(); 2
ViewCriteriaRow
ViewCriteriaRow noPromRow
noPromRow == vc.createViewCriteriaRow();
vc.createViewCriteriaRow();
promotionRow.setAttribute("OrderTotal",
promotionRow.setAttribute("OrderTotal", ">
"> 500");
500");
promotionRow.setAttribute("CreditLimit",
promotionRow.setAttribute("CreditLimit", ">
"> 2500");
2500");
promotionRow.setAttribute(“DiscountId",
3
promotionRow.setAttribute(“DiscountId", “<>
“<> NULL");
NULL");
noPromRow.setAttribute("OrderTotal",
noPromRow.setAttribute("OrderTotal", ">
"> 1000");
1000");
noPromRow.setAttribute(“CreditLimit",
noPromRow.setAttribute(“CreditLimit", ">
"> 5000");
5000");

vc.addElement(promotionRow);
vc.addElement(promotionRow); 4
vc.addElement(noPromRow);
vc.addElement(noPromRow);
5
custOrdVO.applyViewCriteria(vc);
custOrdVO.applyViewCriteria(vc);
6
custOrdVO.executeQuery();
custOrdVO.executeQuery();

8 - 45 Copyright © 2008, Oracle. All rights reserved.


Iterating Master–Detail Hierarchy

public
public class
class TestClient
TestClient {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
TestClient
TestClient testClient
testClient == new
new TestClient();
TestClient();
String
String amDef
amDef == "oracle.hr.test.TestAM";
"oracle.hr.test.TestAM";
String
String config
config == "TestAMLocal";
"TestAMLocal";
ApplicationModule
ApplicationModule am am ==
Configuration.createRootApplicationModule(amDef,config);
Configuration.createRootApplicationModule(amDef,config);
1 ViewObject
ViewObject dept
dept == am.findViewObject("DepartmentsView1");
am.findViewObject("DepartmentsView1");
dept.executeQuery();
dept.executeQuery();
2
while
while (dept.hasNext())
(dept.hasNext()) {{
3 Row
Row department
department == dept.next();
dept.next();
System.out.println("Department
System.out.println("Department "" ++
4 department.getAttribute("DepartmentId"));
department.getAttribute("DepartmentId"));
5 RowSet
RowSet emps
emps == (RowSet)department.getAttribute("EmployeesView");
(RowSet)department.getAttribute("EmployeesView");
while
while (emps.hasNext())
(emps.hasNext()) {{
6 Row
Row emp
emp == emps.next();
emps.next();
System.out.println("
System.out.println(" Employee
Employee Name:
Name: "" ++
7 emp.getAttribute("LastName"));
emp.getAttribute("LastName")); }} }}
Configuration.releaseRootApplicationModule(am,true);}}
Configuration.releaseRootApplicationModule(am,true);}}

8 - 47 Copyright © 2008, Oracle. All rights reserved.


Finding a Row and Updating
a Foreign Key Value
public
public class
class TestClient
TestClient {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
TestClient
TestClient testClient
testClient == newnew TestClient();
TestClient();
String
String amDef = "oracle.hr.test.TestAM";
amDef = "oracle.hr.test.TestAM";
String
String config
config == "TestAMLocal";
"TestAMLocal";
ApplicationModule
ApplicationModule am am ==
Configuration.createRootApplicationModule(amDef,config);
Configuration.createRootApplicationModule(amDef,config);
1 ViewObject
ViewObject vo vo == am.findViewObject("EmployeesView1");
am.findViewObject("EmployeesView1");
2 Key
Key empKey
empKey == new
new Key(new
Key(new Object[]{101});
Object[]{101});
3 Row[] empsFound = vo.findByKey(empKey,1);
Row[] empsFound = vo.findByKey(empKey,1);
if
if (empsFound
(empsFound != != null
null &&&& empsFound.length
empsFound.length >> 0)0) {{
Row
Row emp
emp == empsFound[0];
empsFound[0];
4 System.out.println("Employee
System.out.println("Employee Name: Name: "" ++ emp.getAttribute("LastName"));
emp.getAttribute("LastName"));
System.out.println("Employee
System.out.println("Employee is in department ““ ++
is in department
5
emp.getAttribute("DepartmentId"));
emp.getAttribute("DepartmentId"));
6 emp.setAttribute("DepartmentId",60);
emp.setAttribute("DepartmentId",60);
7 System.out.println("Employee
System.out.println("Employee reassigned
reassigned to to department
department "" ++
emp.getAttribute("DepartmentId"));
emp.getAttribute("DepartmentId"));
8 am.getTransaction().rollback();
am.getTransaction().rollback();
System.out.println("Transaction
System.out.println("Transaction cancelled");}
cancelled");}
Configuration.releaseRootApplicationModule(am,true);
Configuration.releaseRootApplicationModule(am,true); }} }}

8 - 48 Copyright © 2008, Oracle. All rights reserved.


Creating a New Row

public
public class
class TestClient
TestClient {{
public
public static void
static void main(String[]
main(String[] args)
args) {{
TestClient
TestClient testClient
testClient == new new TestClient();
TestClient();
String
String amDef = "oracle.hr.test.TestAM";
amDef = "oracle.hr.test.TestAM";
String
String config
config == "TestAMLocal";
"TestAMLocal";
ApplicationModule
ApplicationModule am =am =
Configuration.createRootApplicationModule(amDef,config);
Configuration.createRootApplicationModule(amDef,config);
1 ViewObject
ViewObject vo vo == am.findViewObject("EmployeesView1");
am.findViewObject("EmployeesView1");
Row newEmp = vo.createRow();
2 Row newEmp = vo.createRow();
vo.insertRow(newEmp);
vo.insertRow(newEmp);
newEmp.setAttribute("EmployeeId",999);
newEmp.setAttribute("EmployeeId",999);
newEmp.setAttribute("FirstName","Pam");
3 newEmp.setAttribute("FirstName","Pam");
newEmp.setAttribute("LastName","Gamer");
newEmp.setAttribute("LastName","Gamer");
Date
Date now
now == new
new Date();
Date();
newEmp.setAttribute("HireDate",now);
newEmp.setAttribute("HireDate",now);
newEmp.setAttribute("JobId","IT_PROG");
newEmp.setAttribute("JobId","IT_PROG");
newEmp.setAttribute("Email","[email protected]");
newEmp.setAttribute("Email","[email protected]");
newEmp.setAttribute("DepartmentId",60);
newEmp.setAttribute("DepartmentId",60);
newEmp.setAttribute("ManagerId",103);
newEmp.setAttribute("ManagerId",103);
4 am.getTransaction().commit();
am.getTransaction().commit();
System.out.println("Added
System.out.println("Added employeeemployee "" ++
5 newEmp.getAttribute("EmployeeId")
newEmp.getAttribute("EmployeeId") ++ "" to to Department
Department "" ++
newEmp.getAttribute("DepartmentId"));
newEmp.getAttribute("DepartmentId"));
Configuration.releaseRootApplicationModule(am,true);
Configuration.releaseRootApplicationModule(am,true); }} }}

8 - 49 Copyright © 2008, Oracle. All rights reserved.


Summary

In this lesson, you should have learned how to:


• Generate Java classes for business components
• Override class methods
• Implement programmatic modifications
• Add service methods to an application module
• Create a test client
• Use business component client APIs

8 - 50 Copyright © 2008, Oracle. All rights reserved.


Practice 8 Overview:
Programmatically Modifying
Business Components

This practice covers the following topics:


• Generating Java classes
• Overriding base class methods
• Using a test client to enable testing code that uses some of
the view object APIs
• Extending the application module base class
• Adding service methods to an application module

8 - 51 Copyright © 2008, Oracle. All rights reserved.

You might also like