Tuesday, December 23, 2008
Learning ADF
--> Basic java - http://java.sun.com/docs/books/tutorial/java/index.html
--> J2EE - http://www.amazon.com/Certified-Component-Developer-Study-Companion/dp/0955160316
--> JSF - http://www.javapassion.com/j2ee/JSFBasics_speakernoted.pdf
--> XML concepts - http://www.w3schools.com/xml/default.asp
I will be posting my ADF 11g learning application by next year.
Happy Learning.
Tuesday, October 14, 2008
Call method on page load in ADF
In this example we will see how we can call a method inside your backing bean or application module when page is getting loaded.
The scenario I am taking here is you have to show the current row index of the view object row on page load in ADF table column.
1) Create a view object based on Job table in HR schema with name OnPageLoadJobVO. Do generate the VOImpl and VORowImpl java classes for the created view object.
2) Add a transient variable inside your view object with name
“myCurrentRowIndex”
3) Add the above created view Object inside your application module.
4) Add the following code inside your application module Impl class.
public void setJobCurrentRowIndex() {
System.out.println("I am here inside AM");
OnPageLoadJobVOImpl vo = getOnPageLoadJobVO1();
OnPageLoadJobVORowImpl row=null;
long fetchedRowCount = vo.getEstimatedRowCount();
RowSetIterator jobVoIter = vo.createRowSetIterator("jobVoIter");
if (fetchedRowCount > 0)
{
jobVoIter.setRangeStart(0);
jobVoIter.setRangeSize((int)fetchedRowCount);
for (int count = 0; count < fetchedRowCount; count++)
{
row=(OnPageLoadJobVORowImpl)jobVoIter.getRowAtRangeIndex(count);
row.setmyCurrentRowIndex(new Number(count));
}
}
jobVoIter.closeRowSetIterator();
}
5) Expose the above created method in application module to the client.
6) Drag and drop the OnPageLoadJobVO object to your jspx page as ADF read only table.
7) Create a new Managed bean using faces-config.xml with
name= OnPageLoadBackingBean and
8) Copy and paste the following code inside your newly created managed bean class.
package viewlayer.backing;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import model.common.AppModule;
import oracle.adf.controller.v2.lifecycle.Lifecycle;
import oracle.adf.controller.v2.lifecycle.PagePhaseEvent;
import oracle.adf.controller.v2.lifecycle.PagePhaseListener;
public class OnPageLoadBean implements PagePhaseListener{
public OnPageLoadBean() {
}
public void afterPhase(PagePhaseEvent event) {
}
public void beforePhase(PagePhaseEvent event) {
if (event.getPhaseId() == Lifecycle.PREPARE_MODEL_ID) {
if (!isPostback())
/*
System.out.println("i am here inside backing bean");
this.getApplicationModule().setJobCurrentRowIndex();
}
}
private boolean isPostback() {
return Boolean.TRUE.equals(resolveExpression("#{adfFacesContext.postback}"));
}
private Object resolveExpression(String expression) {
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
ValueBinding bind = app.createValueBinding(expression);
return bind.getValue(ctx);
}
private AppModule getApplicationModule() {
return (AppModule)resolveExpression ("#data.AppModuleDataControl.dataProvider}");
}
}
9) Right click on your jspx page and go to your page definition. Where set the attribute ControllerClass inside your pageDefinition tag as the name of the managed bean.
Run your page to check the results.
Add new row in ADF table on button click
In this example we will add a new row at last position in an ADF table. I am taking an example of Employee table in HR schema. We need this approach if we want to create an empty row in ADF table and then initialize it with some values or to add the empty row at the end of the table.
Step 1) Create a new Employee View Object(say EmpViewObjEOBased) based on an Employee Entity object.
Step 2) Add the above view object in your application module.
Step 3) Drop it on your page as a ADF table (not as ADF readonly table).
Step 4) Add the following code inside your application module class.
public void createRow() {
Row newRow = getEmpViewObjEOBased1().createRow();
newRow.setNewRowState(Row.STATUS_INITIALIZED);
//get instance of the above created view object
ViewObjectImpl vo=getEmpViewObjEOBased1();
// to insert row at the end of the table
vo.insertRowAtRangeIndex(vo.getRangeSize()-1,newRow);
System.out.println(getEmpViewObjEOBased1().getCurrentRowIndex());
}
If you want to insert the row at the begening of the table replace line vo.insertRowAtRangeIndex(vo.getRangeSize()-1,newRow); with
vo.insertRow(newRow);
Step 5) Expose this application module method to client.
Step 6) Drop the createRow button inside the “Table facets->action” as a ADF command button.
Wednesday, October 8, 2008
Jdeveloper 11g production
Ready for download.
http://www.oracle.com/technology/software/products/jdev/htdocs/soft11.html .
JDeveloper 11g — Online Demonstrations
http://www.oracle.com/technology/products/jdev/viewlets/11/index.html
Documentation and Developer guide
Important code samples commonly used in ADF
In this post I am listing up important code samples commonly used in ADF .
Code to access the application module methods from the managed bean
To make sure that your application module method is accessible from the view layer, in the application module editor, do shift the method from “Avaliable” to “Selected List” under the client interface option.
FacesContext fc = FacesContext.getCurrentInstance();
ValueBinding vb = fc.getApplication().createValueBinding("#{data}");
BindingContext bc = (BindingContext)vb.getValue(fc);
DCDataControl dc = bc.findDataControl("HRAppModuleDataControl");
ApplicationModule am = (ApplicationModule)dc.getDataProvider();
HRAppModule hrAm = (HRAppModule)am;
hrAm.setCurrentEmpRow(empId1);
In the above example HRAppModuleDataControl is the Data control used in your application.You can find the exact name used in your application in the DataBindings.cpx file inside the
Code to access the page bindings from the Managed bean
DCBindingContainer bc1 = this.getBindings();
String empId1 = bc1.findIteratorBinding("EmpDeptTableIterator").
getCurrentRow().getAttribute("EmployeeId").toString();
In the above example EmpDeptTableIterator is the iterator name from which I want to access the EmployeeId.
In the above example getBinding() refers to the method which returns the object of type DCBindingContainer. If its not already there, add the following code snippet to your same managed bean.
private DCBindingContainer bindings;
public DCBindingContainer getBindings()
{ return bindings;
}
public void setBindings(DCBindingContainer bindings)
{ this.bindings = bindings; }
An inside your faces-config.xml add the following managed property inside your managed bean.
<managed-property>
<property-name>bindings</property-name>
<property-class>oracle.adf.model.binding.DCBindingContainer</property-class>
<value>#{bindings}</value>
</managed-property>
How to create the Simple Login page in ADF
Step 1) Create a read only View Object with bind variable with name EmpLoginViewObj. Following is the SQL query:-
SELECT
EMPLOYEES.EMPLOYEE_ID EMPLOYEE_ID,
EMPLOYEES.FIRST_NAME FIRST_NAME,
EMPLOYEES.LAST_NAME LAST_NAME
FROM
EMPLOYEES
WHERE EMPLOYEES.LAST_NAME =:LastName
Create the bind variable with name LastName. Make sue that you are generating the ViewObjImpl class for the above created view object.
Step 2) Add the above created View object in the Application module.
Step 3) Add the following code in the application module's Java Impl class
public void checkLoginCredentials(String ename,String pwd_form)
{
System.out.println(ename + " " + pwd_form);
EmpLoginViewObjImpl vo = (EmpLoginViewObjImpl)getEmpLoginViewObj1();
//set the bind variable value to last name
vo.setNamedWhereClauseParam("LastName",pwd_form);
vo.executeQuery();
int rowCount=vo.getEstimatedRangePageCount();
System.out.println("rowCount="+rowCount);
if(rowCount==0) {
throw new JboException("Password doesn't match");
}
}
Import oracle.jbo.JboException class in the AMImpl class.
Step 4) Expose the above method in the Client Interface of the application module.
Step 5) Create three jspx pages. LoginPage.jspx, WelcomePage.jspx and FaliurePage.jspx
Step 6) Drag and drop the checkLoginCredentials on your LoginPage.jspx page as the parameter->ADF parameter Form.
Step 7) Double click the command button on LoginPgae.jspx and define a new action binding by first defining the managed bean(with Name backing_LoginPage) and action binding method name as loginBtn_action()
Step 8) Add the following code inside your loginBtn_action() method.
public String commandButton_action() ()
{
String returnStr="error";
System.out.println("Inside loginBtn_action");
BindingContainer bindings = getBindings();
OperationBinding operationBinding =
bindings.getOperationBinding("checkLoginCredentails");
Object result = operationBinding.execute();
System.out.println(result);
if (operationBinding.getErrors().isEmpty()) {
returnStr= "success";
}
System.out.println("returnStr= " + returnStr);
return returnStr;
}
Step 8 ) Set the navigation rule as
<navigation-rule>
<from-view-id>/LoginPage.jspx</from-view-id>
<navigation-case>
<from-action>#{backing_LoginPage.commandButton_action}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/WelcomePage.jspx</to-view-id>
</navigation-case>
<navigation-case>
<from-action>#{backing_LoginPage.commandButton_action}</from-action>
<from-outcome>error</from-outcome>
<to-view-id>/FaliurePage.jspx</to-view-id>
</navigation-case>
</navigation-rule>
run your login page to check the results.
Monday, October 6, 2008
How to apply the CSS in the ADF Application
-> A CSS file that defines the actual look of the components
-> A configuration file. In our case it will be "adf-faces-skins.xml" which lists up all skins available for our application (not including Oracle, Minimal, and Simple). This file has to be located in your applications WEB-INF directory
-> An entry in the ADF Faces configuration file - adf-faces-config.xml
Creating a CSS file:
1) Right-click the project that contains the code for the user interface and choose
2) New to open the New Gallery.
3) In the New Gallery, expand the Web Tier node and select HTML.
4) Double-click CSS File.
5) Complete the Create Cascading Style Sheet dialog by giving CSS name.
6) Add various styles according to your requirement in the CSS
Register the CSS file:
1) Right-click your view project and choose New to open the New Gallery.
2) The New Gallery launches. The file launches in the Source editor.
In the Categories tree on the left, select XML. If XML is not displayed, use the
Filter By dropdown list at the top to select All Technologies.
3) In the Items list, select XML Document and click OK.
4) Name the file adf-faces-skins.xml, place it in the
5) Replace the generated code with the code shown in
<?xml version="1.0" encoding="ISO-8859-1"?>
<skins xmlns="http://xmlns.oracle.com/adf/view/faces/skin">
<skin>
<id>id name</id>
<family>family name</family>
<render-kit-id>oracle.adf.desktop</render-kit-id>
<style-sheet-name>path to CSS</style-sheet-name>
</skin>
</skins>
Configure an application to use a skin:
1) Open the adf-faces-config.xml file.
2) Replace the <skin-family> value with the family name for the skin you wish to use
Wednesday, May 7, 2008
Friday, April 25, 2008
ADF Learning 7 - Show Hide button in ADF faces
ADF Learning 6 - Dependent List Boxes
ADF Learning 4 - Create Employee page
ADF Learning 3 - Navigating to detail page
ADF Learning 2 - Displaying Data on the page
Thursday, April 24, 2008
Starting up with ADF
Tuesday, April 8, 2008
Help Questions in OAF.......part -3
Answer:
oracle.jbo.domain.Date currentJvmDate = new oracle.jbo.domain.Date(System.currentTimeMillis());
Q: To construct an oracle.jbo.domain.Date object for current database system time?
Answer:
oracle.jbo.domain.Date currentDbDate =rootAM.getOADBTransaction().getCurrentDBDate();
Q: To determine if an oracle.jbo.domain.Date is the passedDate?
Answer:
public boolean isPassedDate(Date value)
{
// ensures that this mandatory attribute has a nonnull
value.
if (value != null)
{
OADBTransaction transaction = this.getOADBTransaction();
long sysdate = transaction.getCurrentDBDate().dateValue().getTime();
long startDate = value.dateValue().getTime();
if (startDate < sysdate)
{
return true;
}
}
return false;
}
Q: To round off the real number upto two digits?
Answer:
public String roundOffToTwoDigit(String number)
{
DecimalFormat formatter= new DecimalFormat("###.##");
double numberD = Double.parseDouble(number);
return formatter.format(numberD);
}
public double roundOffToTwoDigit(double number)
{
try
{
DecimalFormat formatter= new DecimalFormat("#.00");
formatter.setMaximumFractionDigits(2);
formatter.setMinimumFractionDigits(2);
return new Double(formatter.format(number)).doubleValue();
}
catch(java.lang.NumberFormatException e)
{
e.printStackTrace();
}
return 0.0;
}
Q: I have an entity object-based view object and I use vo.clearCache.However I am getting oracle.jbo.TooManyObjectsException?How to solve this?
Answer:
When you clear the view object cache with vo.clearCache(), it does NOT clear the entity cache nor change the states of entities. Thus, if you try to insert the row with a key value that already exists in the entity cache; you get TooManyObjectsException.The solution is to remove on all
the rows in the view object.
Answer:
Possible reason could be of inserting the record with duplicate primary key.
Q: How do I determine the transaction state -- that is, whether changes have been made to view objects or not?
Answer:
We can use
-->OAViewObject.isDirty() - This method tells you whether a particular view object contains changes or not. This works for both entity object-based view objects and view objects
based on OAPlsqlViewObjectImpl
/* @sourceVO: source VO contains the data in the UI
* @destVO: dest VO contains the data fetched from the
database, should not be
* based on EO
*/
private boolean isVODataDirty(ViewObjectImpl sourceVO,
ViewObjectImpl destVO)
{
boolean dirtyDataFlag=false;
if (sourceVO == null destVO == null)
{
return false;
}
else if(sourceVO.getRowCount()!=destVO.getRowCount())
{
return true;
}
AttributeDef[] attrDefs = sourceVO.getAttributeDefs();
int attrCount = (attrDefs == null)? 0 : attrDefs.length;
/*if no attributes are there in the VO*/
if (attrCount == 0)
{
return false;
}
/* Create a row set iterator on the source view object
to use for copy operation*/
RowSetIterator compareIter = sourceVO.findRowSetIterator("compareIter");
if (compareIter == null)
{
compareIter = sourceVO.createRowSetIterator("compareIter");
}
int count=0;
/*Sets the range size for the iterator,-1 for all
rows are to be included.*/
destVO.setRangeSize(-1);
/*loop for the VO rows*/
while (compareIter.hasNext())
{
Row sourceRow = compareIter.next();
Row destRow = destVO.getRowAtRangeIndex(count);
/*loop for the VO Attribute*/
for (int i = 0; i < attrCount; i++)
{
byte attrKind = attrDefs[i].getAttributeKind();
/*compare the data only if the attribute
is persistent*/
if(attrKind==AttributeDef.ATTR_PERSISTENT)
{
String attrName=attrDefs[i].getName();
if (destVO.lookupAttributeDef(attrName) != null)
{
Object sourceAttrVal = sourceRow.getAttribute(attrName);
Object destAttrVal = destRow.getAttribute(attrName);
if(destAttrVal!=null && sourceAttrVal!=null)
{
if(!sourceAttrVal.equals(destAttrVal))
{
dirtyDataFlag=true;
compareIter.closeRowSetIterator();
return dirtyDataFlag;
}
}
/*if values are not equal then it
means data is dirty*/
if((sourceAttrVal==null && destAttrVal!=null)
(sourceAttrVal!=null && destAttrVal==null))
{
dirtyDataFlag=true;
compareIter.closeRowSetIterator();
return dirtyDataFlag;
}
}
}
}
count++;
}
compareIter.closeRowSetIterator();
destVO.reset();
/*data is not dirty*/
return dirtyDataFlag;
}
Q: When I am executing the VO query and after that fetching the attribute value from the VO, getting the NullPointerExecption?How to handle it?
Answer:-When you execute the VO.executeQuery() method, and if your query is fetching the record, then row pointer is at position -1. Either call the vo.first() method or call vo.setCurrentRowRangeIndex(0);
Q: I have two radio buttons with are the part of the same group, when I am submitting the page, control is jumping in to the last radio button? How I can solve this problem?
Answer:-Just put your individual radio button under the flowlayout which intern should be put under the cell format.
Q: I have two advance tables in my page. And both of them have "Add Another Row" button, now How I can identify that which "Add Another button" is clicked?
Answer: By calling the pageContext.getParameter(SOURCE_PARAM) will return the name
of the Advance table against which the Add Another Radio button is clicked.
Q: I have two radio buttons in my page. When I am submitting the page, the control is jumping to last radio button in my page?
Answer:
Use messageRadioButtons and group them under same name and add each radio button under the separate cellformat region.
Answer: Execute following command in SQL exec JDR_UTILS.printDocument('
example
JDR_UTILS.printDocument('/who/oracle/apps/xxwrp/prt/whoreg/
webui/XXWRP_GoodsRegistrationPG');
And to list of the PG files in particular top, execute the
following command:-
exec JDR_UTILS.listDocuments('path');
example
exec
JDR_UTILS.listDocuments('/who/oracle/apps/xxwrp/prt/whoreg/
webui/');
Q: Is there a way to determine if someone has used the personalize links on a Self-Service Web Applications page?
Answer:
Here are several ways to identify if there are Personalization’s made to a page and what those
Personalization’s are:
2. Another way is to use the Functional Administrator. The first thing to do to use the Functional Administrator is to identify the Document Path. For example, go to the Notifications link from the Workflow User Web Applications responsibility, and then click on the Personalize Page link. Notice that the Document path for the Notifications page is: /oracle/apps/fnd/wf/worklist/webui/NotificationsPG. From the Functional Administrator responsibility Home page, click on the Personalization tab in the upper left hand corner. Insert the document path for the document you want to check - for example: Document Path = /oracle/apps/fnd/wf/worklist/webui/NotificationsPG and then click on the 'Go' button to get a list of Personalization’s for this page.
3. A third way to check to see if there are personalization’s on a page is to use sqlplus and run the
JDR_UTILS program. You will need the Document path to the page in question - again using the Document path for the Notifications page: /oracle/apps/fnd/wf/worklist/webui/NotificationsPG
Run the listDocuments function to drill down and find all documents that have been personalization’s under a certain Meta Data region:
set serveroutput on
exec
JDR_UTILS.listDocuments('/oracle/apps/fnd/wf/worklist/webui
/');
/oracle/apps/fnd/wf/worklist/webui/customizations/
Note, you do not include the Page ID (NotificationsPG) with this query. In my test case, notice that there are 'customizations' in this MDS region webui. The 'customizations' indicates that personalization’s have been made to the 'webui' region. Run the query again with the new path and notice that there are 'site' level customizations, although there could be other levels such as user, responsibility, ...:
exec
JDR_UTILS.listDocuments('/oracle/apps/fnd/wf/worklist/webui
/customizations/');
/oracle/apps/fnd/wf/worklist/webui/customizations/site/
Run the query again with the new path and notice that the customizations are at site level '0':
exec
JDR_UTILS.listDocuments('/oracle/apps/fnd/wf/worklist/webui
/customizations/site/');
/oracle/apps/fnd/wf/worklist/webui/customizations/site/0/
Run the query one more time with the new path and notice that the customizations are made to the 'NotificationsPG':
exec
JDR_UTILS.listDocuments('/oracle/apps/fnd/wf/worklist/webui
/customizations/site/0/');
/oracle/apps/fnd/wf/worklist/webui/customizations/site/0/No
tificationsPG
Once we have identified a particular page or pages that have customizations/personalization, then we can use the printDocument to see what personalization’s have been made
to the page:
exec
JDR_UTILS.printDocument('/oracle/apps/fnd/wf/worklist/webui
/customizations/site/0/NotificationsPG');
-------------
xml:lang="en-US"
customizes="/oracle/apps/fnd/wf/worklist/webui/NotificationsPG">
-------------
As you can see, rendered has been set to "false" for "MainRegion.NtfView". You can then use the deletedocument function to remove this personalization exec jdr_utils.deletedocument('/oracle/apps/fnd/wf/worklist/webui/customizations/site/0/NotificationsPG');
Q: How to remove a bad personalization from an OA Framework page?
Answer:
) Login to Oracle Applications with the system administrator responsibility
2) Update the Profile Option: "Disable Self-Service Personal" = YES
- This disables the rendering of all personalization that have been created.
- You can set this at the site or user level.
3) Navigate to the page you personalized.
4) Enter the personalization UI in the same way you did to create the personalization initially
5) Click the Delete button at the bottom of the page.
- This will remove the personalization from the page.
6) Go back to Oracle Apps with the system administrator responsibility
7) Re-enable personalizations by setting the "Disable Self- Service Personal" profile option to NO
Q: How to pass a Date to a VO for executing the Query?
Answer:
Oracle.jbo.domain.date dateToPass=
java.sql.Date javaSqlDate=dateToPass.dateValue();
dateToPass = new Date(javaSqlDate);
vo.setWhereClauseParam(1,dateToPass);
vo.executeQuery();
Q: How I can bind the property of a UI widget to a VO attribute at design time and at run time?
Answer:
At design time we have to use SPEL. Suppose to have to bind the disable property of a UI widget to the VO attribute. Then specify ${oa.
OAMessageLovInputBean beanObj = (OAMessageLovInputBean)webBean.findIndexedChildRecursive("<>");
beanObj.setAttributeValue(DISABLED_ATTR,new
OADataBoundValueViewObject(beanObj, "
Q: How I can change the values of the Categories (Category drop down) in the standard OAF Attachment page?
Answer:
String []maps=
OAAttachmentTableBean attchmentBean=(OAAttachmentTableBean)webBean.findIndexedChi
ldRecursive("AttachmentTable");
attchmentBean.setCategoryMap(
Q: How I can set the Currency Code(Currency format) for a particular UI field?
Answer:
String formatter = "USD";
OAMessageStyledTextBean regUSDAmtBean=(OAMessageStyledTextBean)webBean.findIndexedChildRecursive("USDTotalAmt");
if (regUSDAmtBean != null)
{
regUSDAmtBean.setAttributeValue(CURRENCY_CODE,formatter);
}
Q: How to get the handle to a particular row of the Advance table?
Answer:
--------------Inside CO---------------------------------------------------------------------
String rowReference =
pageContext.getParameter(OAWebBeanConstants.EVENT_SOURCE_ROW_REFERENCE);
Serializable[] params = { rowReference };
am.invokeMethod("getHandleToRow",params);
---------------------------------------------------------------------------------------------
------------Inside AM------------------------------------------------------------------------
public void getHandleToRow()
{
OARow row = (OARow)findRowByRef(rowReference);
-------
}
Thursday, April 3, 2008
Help Questions in OAF.......part -2
Answer:
/*Call the following logic in processFormRequest method of
the web bean's controller that contains the table bean.*/
String value = pageContext.getParameter("value");
if (value != null)
{
int newValue = Integer.parseInt(value);
if (tableBean.getValue() < newValue)
// next pressed.
else
// previous pressed.
}
Q: Is there a method for setting the length of the fields in a poplist? It seems to be sized to the length of the largest value in the list?
Answer:
This is the standard HTML behavior. The only method available to you is to truncate the values being passed to the poplist.
Q: Is there any way to check whether a field from the base page, that an LOV is dependent on, is blank?
Answer:
In OA Extension, set the Required property to yes for the field (region item). If the field is blank, the LOV will generate an exception.
Q: How do I handle raising an unexpected database error and passing that back to the instantiating page?
Answer:
To handle database errors that occur within a PL/SQL procedure called through Java, code a standard exception handler for 'when others' within the PL/SQL procedure. The 'when others' exception handler should call FND_MSG_PUB.ADD_EXEC_MSG (pkg_name, proc_name,
substr(sqlerrm, 1, 240)). This registers the database error in the standard FND error stack.
You can then catch and throw that exception in the insertRow and updateRow methods using the procedure OAExceptionHelper.checkErrors (Tx, messageCount, returnStatus, messageData).
Q: To convert oracle.jbo.domain.Date ==> java.util.Date?
Answer:
oracle.jbo.domain.Date oracleDate =
java.sql.Date javaSqlDate = oracleDate.dateValue();
long javaMilliSeconds = javaSqlDate.getTime();
java.util.Date javaUtilDate = new java.util.Date(javaMilliSeconds);
Q: To convert java.util.Date ==> oracle.jbo.domain.Date?
Answer:
java.util.Date javaDate =
long javaMilliseconds = javaUtilDate.getTime();
java.sql.Date javaSqlDate = new java.sql.Date(javaMilliseconds);
oracle.jbo.domain.Date oracleDate = new oracle.jbo.domain.Date(javaSqlDate);
Friday, March 14, 2008
Help Questions in OAF.......part -1
Answer:
Example:-
OAMessageRadioButtonBean amountBasedRBBean =
(OAMessageRadioButtonBean)
webBean.findIndexedChildRecursive("AmountBasedRB");
OAMessageRadioButtonBean rateBasedRBBean =
(OAMessageRadioButtonBean)
webBean.findIndexedChildRecursive("RateBasedRB");
amountBasedRBBean.setName("AmountRadioGroup");
amountBasedRBBean.setValue("A");
rateBasedRBBean.setName("AmountRadioGroup");
rateBasedRBBean.setValue("R");
Q: After clicking submit button in OAF page,processFormRequest doesn’t get called. How do I correct this?
Answer:
Possible Solution:-Go to Tools-->Preferences-->Embedded
OC4J--> and confirm that the "Default Local IP Address"
option is selected.
Q: Clicking "Add another Row" button in a table results to “state loss” error on the page. How should I resolve this? (Classic and Advanced)
Answer:
This happens when you have not executed the view object
associated with the table. For any successful table event,
the underlying table view object query must have been
executed before a table event is caused. In the case where
you don't want to display any rows when the page comes up,
yet want to select on "Add Another Row" to add rows into
the table, then before you add rows to the table, you must
properly initialize the view object.
Q: One of the most common errors we all face in OAF is "oracle.apps.fnd.framework.OAException:java.lang.NullPointerException". How should I resolve this?
Answer:
The primary cause of this error is beacuse of you are
trying to fetch the data from the VO, which
does't contains any data.
For example:-
1)XXWRP_ServiceRegVORowImpl
serviceRegVORow=(XXWRP_ServiceRegVORowImpl)getXXWRP_Service
RegVO1().getCurrentRow();
2)Date value=serviceRegVORow.getCompletionDate();
Now if the XXWRP_ServiceRegVO1 is not executed, then above
code will throw error at line number 2.To avoid this,
either handle NullPointerException or check if the
serviceRegVORow is null or not.
Q: How do find out the selected view object rows using the table selector? (Classic and Advanced)?
Answer: - Place this logic in your view object and invoke
it with invokeMethod from AM.
int fetchedRowCount = getFetchedRowCount();
if (fetchedRowCount > 0)
{
// Save the original range size and range start.
int savedRangeSize = getRangeSize();
int savedRangeStart = getRangeStart();
/* Alter the range size and start in this order to
prevent any accidental row fault-in from the
database. */
setRangeStart(0);
setRangeSize(fetchedRowCount);
Row[] rows = getAllRowsInRange();
for (int i = 0; i < fetchedRowCount; i++)
{
if(rows[i]!=null &&
"Y".equals(rows[i].getAttribute("SelectFlag")))
{
/*operation to be performed on row*/
}
}
}
/*Restore the range size and start. Do in the following
order to prevent any accidental row fault-in. Reverse
order upon restoring to a potentially smaller range size.*/
setRangeSize(savedRangeSize);
setRangeStart(savedRangeStart);
Tuesday, January 22, 2008
Introduction to OA Framework.
The Model: -
The model component is implemented using the BC4J. BC4J consists of three components:-
-->Entity Object and Associations.
-->View Object and View Link objects.
-->Application Module.
Entity Object: - Entity Objects represents a database row in middle-tier. Database rows are
represented as individual entities, in which attributes typically correspond to columns in the
corresponding table to automatically implement queries, inserts, updates and deletes. Entity
objects can also be based on views, synonyms or snapshots. Most entity objects that you create
subclass the oracle.apps.fnd.framework.server.OAEntityImpl class. Entity Objects are also used
to implement the business validations. Associations are used to establish the relationship between the entity objects. When you create an Entity Object, framework will provide you a Java class with the setter and getter methods corresponding to each column of the table to which you’re Entity Object is based on. And along with that it will provide you following methods which are called by framework itself on appropriate event:-
protected void validateEntity( ) - Any validation involving two or more attribute values on the
entity should be included in the validateEntity() method.
public void create() - add any defaulting/initialization code, such as getting the value of a
sequence and then assigning it to the corresponding attribute.
public void remove() - If you need to implement any special delete behavior (like
checking to see whether the delete action is allowed, or implementing cascade-delete), you should
add code to your entity's remove() method.
View Object:-
View Object accesses the result set of a SQL statement. It can be either based on the Entity Object or on plain SQL query. A view object is a business component that encapsulates
SQL code and metadata that maps columns in the select statement to the attributes of one or more entity objects, if it is based on the Entity Object. A view object use SQL to join, filter or sort
business data or to shape it for presentation. View objects provide row sets that can be viewed or used to update the underlying entity objects. You can define multiple view objects per entity object or a view object can select data from multiple entity objects. View Object can be created
declaratively or programmatically. Which ever way you create it, you need an application module to contain it. View objects are not an appropriate home for business logic; we should not be writing validation rules in our view objects or view rows. All view objects that you createsubclass the oracle.apps.fnd.framework.server.OAViewObjectImpl class.
Application Module: -
A logical container that manages and provides access to "related" BC4J model objects. It
represents the data model that client uses. To create the data model, the application module
contains business components, including instances of view objects and view links. An application
module may be a root application module or a nested application module. A root application
module is not contained in another application module. It provides transaction context for all
objects it contains. Root application module also maintains the database connection. All application modules that you create subclass the oracle.apps.fnd.framework.server.OAApplicationModuleImpl class.
The View:-
The View formats the data and presents the data to the user. In OAF View is implemented using
the UIX. UIX uses XML to describe the components and hierarchy that make up an application
page. UIX also provides runtime capabilities to translate that metadata into HTML output so that it can be shown on a Browser or a mobile device. The metadata used to describe the UI is loaded into a database repository, called Meta Data Services (MDS), at deployment time and optionally at design time as well. Pages are developed declaratively using the Oracle 9i Jdeveloper OA Extension. Pages are made up of hierarchy of regions and items. Each UI widget corresponds to one or more Java objects (beans). And these java beans are used to create the HTML at runtime. When you design a page, you store "page definition" in XML format on your local machine. When deploying to our system/server, we load this XML file into MDS repository using the xml import statements. When the user run the page in the browser, the page definition is fetched from the MDS repository and is converted into the XML file by the MDS engine. Each component in XML is translated into the Java web bean object. And this web bean is rendered by the OA Framework. Page definition is cached in to the memory, and if it is there, framework will not go to MDS repository to get the page definition.
The Controller responds to user action and direct application flow. It provides the wiring between the UIX web bean and the middle-tier. All the controllers that we create subclass the
oracle.apps.fnd.framework.webui.OAControllerImpl. When the browser issues an OA.jsp request:-
The oracle.apps.fnd.framework.webui.OAPageBean(the main OA Framework page processing class) uses the page name to determine which root AM it refers to, so that the VO’s related to the page can be accessed. Then user session is validated and then OAPageBean evaluates request parameter or figure out if it dealing with an HTTP POST or GET request. During the iteration, if the framework finds a web bean referencing a controller class it will call one of the following methods.
custom code can call the application module to initialize and query the data. This phase may
optionally construct or modify the web beans to create or alter the page structure and web bean
properties.
Process Form Data - This phase is invoked upon a browser 'Post'. During this phase the
framework will automatically applies form changes back to the underlying view objects. Rarely is
custom code required in this phase. If exceptions are thrown during this phase, the Process Form Request phase is skipped and the page is redisplayed.
Process Form Request - This phase is invoked upon a browser 'Post', assuming no exceptions
were thrown during the Process Form Data phase. This is were custom code can handle the form
submit events and call the application module to process the event.
Framework passes two parameters OAPageContext and OAWebBean to the processRequest and processFormRequest. Following are the usages of OAPageContext parameters.
1. To get and set values of the fields, using oapagecontext.getParameter and
oapagecontext.putParameter
2. For redirecting to the current page or another page. For example to redirecting to current page
itself use oapagecontext.forwardImmediatelyToCurrentPage. Or you may use
oapagecontext.sendRedirect(snewpage)
3. To get a handle to application module(remember we attached AM to page)
oapagecontext.getRootApplicationModule()
4. Write debug messages, using oapagecontext.writeDiagnostics
5. Get message text from FND Message dictionary, using oapagecontext.getMessage
Usages of parameter OAWebBean:-
Remember that webbean represents the hierarchy/structure of components in the page. Hence
using this paremeter object, you can get a handle to any bean/component in that page hierarchy.
Once you have a handle to that bean (say field bean or button bean), you can then invoke methods like setRendered etc to change the behaviour of page at runtime.
Some examples are
1. OAWebBean LastName = oawebbean.findIndexedChildRecursive("personLastName");
Note: In this example, our page must have just one field whose name is personLastName
2. Get a handle to region
OAStackLayoutBean oastacklayoutbean =
(OAStackLayoutBean)oawebbean.findIndexedChildRecursive("stackRegionName");