As Published In
Oracle Magazine
November/December 2007

DEVELOPER: Frameworks


Enhanced Calculation and Validation

By Steve Muench Oracle Employee ACE

Do even more in Oracle Application Development Framework 11g— without code.

In this column, I take another look at the upcoming Oracle JDeveloper and Oracle Application Development Framework (Oracle ADF) 11g release and experiment firsthand with several examples designed to improve developer productivity. This column shows how easy it now is to create calculated attributes, validate foreign key values, constrain mutually dependent attribute values, and define more-complex validation rules without writing any Java code.

To follow along with this article, make sure you're using the Oracle JDeveloper 11.1.1.0 (or later) Technology Preview release, which is available as a free download on Oracle Technology Network at oracle.com/technetwork/products/jdev/11. Furthermore, download the starter workspace.

After extracting the contents of the o67frame.zip file, start by opening the FrameworksNovDec2007.jws workspace in Oracle JDeveloper. Note that the starter workspace defines a familiar set of Emp and Dept entity objects, an EmpView view object, and an HRModule application module. Next, configure the scott connection in the starter workspace to point to the database you'll be using. To do this, expand the Application Resources zone of the Application Navigator, the Connection folder, and the Database node to reveal the scott connection. Right-click the scott connection, and select Properties... to view the database connection settings. Review these settings, and change them, if necessary, to point to the SCOTT database user you'll be working with. Click the Test Connection button to ensure that you can successfully connect to the SCOTT user, and then click OK .

Note that if you are using the free Oracle Database Express Edition, you may need to create a new SCOTT user account with CONNECT and RESOURCE privileges and run the CreateDeptEmpTables.sql script provided in the starter workspace to create the DEPT and EMP tables.

Simplifying Calculated Attributes

Groovy is a standards-based dynamic language for the Java platform, defined as Java Specification Request 241 (JSR 241). It provides a simpler syntax than Java for many common programming tasks, it interoperates seamlessly with any Java class, and it can be both compiled and interpreted on the fly. Oracle ADF 11g provides extensive support for the Groovy language, and the first example in this column demonstrates how to use Groovy expressions to define calculated attributes.

In the starter workspace referenced above, the Emp entity object already has a defined transient attribute called TotalComp. Let's update this attribute definition to be the sum of the employee's salary and that person's commission (as defined by the Sal and Comm attributes, respectively). In the formula, let's accommodate for the fact that Comm and Sal might be null.

In Oracle JDeveloper, double-click the Emp entity in the Application Navigator to open the Entity Object Editor. Click Attributes to go to the Attributes page, and double-click the row in the table containing the TotalComp attribute. In the Attribute Editor dialog box, ensure that the Expression radio button in the Value Type radio group is selected. In the Value field, enter the following formula: 

(Sal!=null?Sal:0)+(Comm!=null?Comm:0)

This formula uses a ternary operator that tests a Boolean condition ( Sal!=null ) to return the value of Sal if it is not null and zero otherwise. It then performs a similar calculation on the value of Comm, and returns the sum of both calculations.

To complete the attribute assignment, go to the Dependencies page of the Attribute Editor, select the Sal attribute in the Available list, and click the Add (right-arrow) button to shuttle it to the Selected list. Perform the same steps to also add the Comm attribute to the Selected list. Finally, click OK to save the changes. To test your changes, right-click the HRModule application module in the Application Navigator and select Run from the menu that appears. When the Business Components Browser - Connect dialog box appears, click Connect . Double-click the Employees view object instance, and change the commission and/or salary values in any row to observe that the total compensation is always kept up to date.

Validating Foreign Keys

The last Frameworks column (September/October 2007), looked at how to define declarative lists of values (LOVs) for a view object attribute to assist users choosing existing foreign key lookup values. Keep in mind that, although these LOVs are handy for end users, they are not a substitute for proper validation of the foreign key at the entity object level. For example, some UI components, such as text fields with a pop-up LOV, allow the user to type a foreign key value directly. Furthermore, in a service-oriented architecture, the foreign keys in entity objects can be set programmatically by another application by use of a Web service interface. Fortunately, the new Key Exists validation rule makes it easy to validate foreign key attributes, making quick work of what is normally a programming chore.

The next example adds a Key Exists validation rule to the Emp entity in the Model project. On the General page of the Entity Object Editor, click the Add Validation Rule button, a green plus sign to the right of the Validation Rules heading on the page (on a smaller monitor, you may need to scroll down to see this section). In the Add Validation Rule dialog box, select Key Exists Validator from the Rule Types list. While on the Rule Definition tab, select WorksInDeptAssoc from the Association Name list. This selection denotes a one-to-many association between the Dept and Emp entity objects that represents the foreign key relationship to be validated. Next, on the Failure Handling tab, enter the error message Department does not exist in the Message Text box. Finally, click OK to define the new validation rule.

Run the HRModule again, and change the value of the department ID of an existing employee to any two-digit invalid number (such as 99). When you commit or navigate to a different row, an exception with your custom error message will be raised.

Constraining Dependent Values

Another common kind of validation involves comparing two attributes in the same row. The next example enforces a rule that says that an employee's commission must be less than that person's salary. This rule will be applied only when both the commission and salary are non-null, and it will be re-evaluated when either the commission or the salary value changes. The enhanced Compare validation rule in Oracle JDeveloper 11g makes this check easy to implement.

On the General page of the Entity Object Editor for Emp, go to the Validation Rules section and click the Add Validation Rule button again. In the Add Validation Rule dialog box, select Compare Validator from the Rule Types list. On the Rule Definition tab, select Comm from the Attribute list and LessThan from the Operator list. From the Compare With list, select Entity Attribute , and select the Sal attribute in the Select Entity Attribute box below. These steps set up the basic comparison in the validation rule. Next, on the Validation Execution tab, enter the formula Sal!=null && Comm!=null in the Conditional Execution Expression field. This field causes the rule to be applied only when the specified condition is true. Note that the expression is case-sensitive, so be sure to type Comm and not comm. Next, go to the Triggering Attributes section, select Sal from the Available Attributes list, and click the Add (right-arrow) button to shuttle Sal into the <,/span> Selected Attribute list, along with Comm . At runtime, when the value of any attribute in this list changes, the rule will be re-evaluated.

Finally, go to the Failure Handling tab and enter the following validation error message in the Message Text box: 

The {attr1} of {val} must be less than 
the {attr2}. 

Be sure to include the three message expressions in curly braces. In the Error Message Expressions table below, click the row for the attr1 token and double-click the Expression cell in that row. Enter the expression source.hints.Comm.label to reference the value of the user-friendly display label for the Comm attribute of the source entity object being validated. Similarly, enter the expression source.hints.Sal.label for the attr2 message token, and enter the expression Comm for the val token to reference the value of the Comm attribute. These message expressions, like those in the calculated attribute example above, use Groovy syntax. Although these are very simple expressions, it's important to understand that developers can leverage the full power of Groovy when necessary. To finish, click OK to define the new rule.

Run the HRModule again to test the rule. Try to enter a value of 13000 for the commission of an existing employee. When you commit, the parameterized error message "The Commission of 13,000 must be less than the Salary" should appear. If you change the value of the salary of an employee with no commission, you can verify that no exception is raised, because the Comm value is null. Finally, you can verify that the triggering attributes work properly, by changing the salary of an employee to a value lower than that person's existing commission.

Writing Groovy Validation Rules

In my final example, I create a more complex validation rule, using the Groovy language. This rule specifies that if an employee belongs to a department whose name ends with the letter s , the salary must be a multiple of 5. This rule requires conditional logic and also accesses an attribute of the associated Dept entity object.

On the General page of the Entity Object Editor for Emp, go to the Validation Rules section and click the Add Validation Rule button again. In the Add Validation Rule dialog box, click the Rule Types list, scroll to the bottom, and select Expression Validator . On the Rule Definition tab, enter the following expression: 

if (Dept?.Dname?.toUpperCase()?.endsWith("S") 
&& Sal % 5 != 0) {
  return false;
}
return true;

Next Steps


 READ more Frameworks

READ more about Oracle JDeveloper 10g and Oracle ADF
oracle.com/technetwork/products/jdev
oracle.com/technetwork/products/jdev/tips/muench/designpatterns

DOWNLOAD
Oracle SOA Suite
 Oracle JDeveloper 11g Technology Preview
starter workspace for this column

The Boolean expression in the if statement references the Dept property of the current Emp object being validated to access the associated Dept entity object (if one exists). Then it references the Dname attribute of that Dept object, converts it to uppercase to perform a case-insensitive comparison, and uses the String class endsWith() method to test whether the Dname value ends with s . Note that instead of writing Dept.Dname.toUpperCase().endsWith() , I've replaced the normal dot operator with Groovy's "?." safe-navigation operator. This operator works like the dot operator to allow navigation from an object to properties on that object. However, if the left-side value is null, the Groovy operator doesn't throw a NullPointerException but instead evaluates to null. Conveniently, when null is encountered in Groovy as a Boolean value, it evaluates to false, so using the ?. operator can make lots of expressions more compact. After this initial check, the expression above uses the integer modulo operator (%) to test whether the salary is a multiple of 5. If the department name ends with s and the salary is not a multiple of 5, then it returns false, which causes the rule to fail. Otherwise, it returns true.

Next, go to the Failure Handling tab. Note that because Groovy validation rules can conditionally raise one of several exceptions, you can add multiple error messages in this tab. The message you select will be used when the validation rule returns false. To add a message, click the Add Message button (denoted by a green plus sign). When the Select Text Resource dialog box appears, click New.... In the Create Text Resource dialog box, enter the value MultipleOfFiveSalForDeptsEndingInSMessage in the Key field, and enter the following error message in the Value field: 

If department name ends in S the salary must be multiple of five. 

Then click Save and Select , and finally click OK to define the new validation rule.

Run the HRModule again, and try to enter a salary of 2001 for an employee in department 30 (SALES) or 40 (OPERATIONS). Then commit the change. Because these department names end with an s and the employee's salary is not a multiple of 5, the application will raise a validation error.

Hopefully, these simple examples will help you understand some of the new declarative development features that will be available in the next major release of Oracle JDeveloper and Oracle ADF. For more information on this new release, see the resources at oracle.com/technetwork/products/jdev/11. If you'd like to learn more about the Groovy language, visit http://groovy.codehaus.org .

 



Steve Muench
has worked for Oracle since 1990. He is a consulting product manager for Oracle JDeveloper and an Oracle ACE who has developed and supported Oracle tools and XML technologies and continues to evangelize them. Muench coauthored Oracle ADF Developer's Guide for Forms/4GL Developers (Oracle, 2006) and wrote Building Oracle XML Applications (O'Reilly Media, 2000). His tips and tricks appear on OTN and in his Dive into ADF blog.

Send us your comments