Defining a Calculated Attribute That Computes a Value from Detail Row Set
This article walks through steps to define and implement an attribute whose data is computed from values of rows from another VO which is a detail to this VO.
I will take the following example:
- DeptView is related To EmpView. - In Dept, I will define an attribute named "AverageSalary". - It will compute average salary of Employees that work for this Dept row.
Define ViewObject's and ViewLink
In the IDE (JDeveloper 9.0.3), define DeptView and EmpView. These VOs built on top of Dept and Emp EO, respectively.
Assuming that DeptView and EmpView did not have a ViewLink between the two, create a new ViewLink as follows:
Select the package in the navigator ("mypackage1" in my example).
Right-mouse click and select "New View Link..."
Enter "DeptToEmpLink" as the name.
Select "Dept" as Source and "Emp" as Destination in the "View Objects" panel.
Select "Deptno" in the "Source Attributes" panel. Select "Deptno" in the "Destination Attributes" panel as well.
On the "View Link Properties" panel, you will see that the "Generate Accessor" checkbox is checked only on the Destination side and not on the Source side. This means that an accessor (an attribute) will be generated on the Source ViewObject (DeptView) that allows you to get the related EmpView rows.
If you want the reverse as well, i.e., for an EmpView row to be able to retrieve the related DeptView row, check the "Generate Accessor" checkbox on the Source side.
Double click on DeptView to bring up the ViewObject wizard. Go to the "Java" panel. Check the checkbox for "Generate Java File" under the label "View Row Class: DeptViewRowImpl". This will cause generation of the .java file (DeptViewRowImpl.java) for the Row class when you press "OK".
Now, open up DeptViewRowImpl.java. You should see a method name "getEmpView()". This is the attribute accessor method that traverses the ViewLink to give you a collection of EmpView rows that are related to this DeptView row.
Define AverageSalary Attribute
Double click on DeptView to bring up the ViewObject wizard. Select the "Attributes" panel. Then, push the "New..." button to define a new attribute.
Enter "AverageSalary" for "Name".
Select "BigDecimal" for "Type".
Press "OK" (to get out of "New View Object Attribute" panel).
Press "OK" (to get out of the View Object wizard).
Now, DeptViewRowImpl.java should have a new method named public BigDecimal getAverageSalary()
Add the following code:
public BigDecimal getAverageSalary() { /* This method call below will return rows from */ /* EmpView that are related to this DeptView row. */ oracle.jbo.RowIterator emps = getEmpView(); oracle.jbo.Row empRow; BigDecimal totSal = new BigDecimal(0.0); int empCount = 0; while ((empRow = emps.next()) != null) { /* Retrieve the salaray attribute value. * In my example, it returns an oracle.jbo.domain.Number. */ oracle.jbo.domain.Number sal = (oracle.jbo.domain.Number) empRow.getAttribute("Sal"); /* Convert it into a BigDecimal. */ BigDecimal salBD = new BigDecimal(sal.doubleValue()); /* Keep adding to the total. */ totSal = totSal.add(salBD); empCount++; } /* Return the average. */ return new BigDecimal(totSal.doubleValue() / empCount); }
What Goes on Here?
When the application code calls either getAttribute("AverageSalary");
or getAverageSalary();
The custom code above is reached.
It calls getEmpView(), which is the View Link accessor method. This causes the detail View Object to be located. A new Row Set is created from this View Object on behalf of the caller. The return value from getEmpView() is a RowSet containing EmpView rows that are related to this DeptView row.
The 'while' loop walks through each of these Employee row and adds up the total salary. As the last step, the average is computed and returned.
10:08:06 AM
|