DEVELOPER: Frameworks

Starting with Oracle ADF

By Steve Muench

Understanding the basics of application organization

In my last column, I described how Oracle JDeveloper 10g and the Oracle Application Development Framework (ADF) give developers familiar with Oracle Forms a familiar rapid application development (RAD) environment and a powerful set of business components for quickly building J2EE applications. In this column, I explore how typical Oracle ADF applications are organized and how to implement basic business rules on your entity objects. I also explain some unique benefits of working with this Java-based application-building framework.

Basic Organization of Oracle ADF Applications

In Oracle Forms Builder, you can work on multiple forms, menus, and PL/SQL libraries at the same time, but there is no formal way of grouping them into an application. Oracle JDeveloper offers a more structured approach, giving you a workspace to contain all of your application elements. Inside a workspace, you arrange your work into multiple projects, each containing a subset of the application's artifacts. Some of the projects may contribute executable code or user interface pages that get deployed as part of the application, and others may contain only SQL scripts, database schema designs, regression tests, or UML diagrams.

When you are creating a new workspace, Oracle JDeveloper and Oracle ADF make it easy to follow the established J2EE best practice of separating your application's business logic and data access layer from its user interface layer. By choosing an appropriate application template, you get a sensible initial set of projects to start with. For a Web application, you get a Model and a ViewController project. These default names come from the popular Model-View-Controller design pattern, which ensures a flexible and easy-to-maintain application architecture. The Model project will contain your business logic and data access components, and the ViewController project will hold your Web pages and page handling logic.

As with anything implemented in Java, your Oracle ADF-powered J2EE applications comprise classes organized into packages. The components you create will live in packages with a prefix such as com.yourcompany.yourapp or org.yourorg.yourapp , whereas the Oracle ADF framework classes themselves live in packages with prefixes such as oracle.adf.model, oracle.adf.controller , or oracle.jbo.

What Goes into Which Project?

Whether you are developing a Web or rich-client Swing application in Oracle JDeveloper, you'll generally start in your Model project, by using the Business Components from Tables wizard to reverse-engineer an initial set of Oracle ADF entity objects and view objects from your existing tables, along with an Oracle ADF application module component to tie all the components together into a service that exposes data for your user interface pages. Recall that entity objects are domain business objects, such as Customer, Order, or Item, that encapsulate business rules and business logic. Your view objects encapsulate the SQL queries required to select, join, filter, and shape the data into the right master/detail data model to fit the needs of your user interface. Your entity objects and view objects cooperate automatically—in the context of the application module that uses them—to let you focus on writing code that's specific to your business functionality.

With at least one application module ready to expose some data, you can start building user interface pages or Swing panels to view and modify data. For Web applications, Oracle ADF uses the popular open source Apache Struts technology to control which pages the end user sees at runtime and in what sequence. In your ViewController project, you use Oracle JDeveloper's visual page flow diagram to iteratively design your user experience, by dropping pages from the palette onto the diagram and connecting them as necessary. Double-clicking on a page opens the WYSIWYG editor so you can work on that page's content.

You'll be pleasantly surprised to discover that putting data onto your pages with Oracle JDeveloper and Oracle ADF is even easier than you might be used to with Oracle Forms. The Data Control palette displays all the services you are working with, any available data sources they expose, and a flexible set of choices for how to visualize them. You can drag data sources and actions from the Data Control palette and drop them onto any page to quickly create scrollable tables, edit forms, drop-down lists, and action buttons. Because Oracle ADF implements the declarative JSR-227 specification for data binding, no code is necessary for building these kinds of interactive pages and the design-time experience is consistent for any kind of user interface or back-end service technology that Oracle ADF supports.

What Sort of Code Do I End Up Writing?

Oracle ADF provides a lot of declarative functionality and spares you from having to understand and implement all the J2EE design patterns required for enterprise J2EE applications. The Java code you do write, as in Oracle Forms with PL/SQL, is only the code that's unique to your specific business application or user interface interactions.

Let's consider the declarative features of an Oracle ADF entity object and some simple examples of custom Java code you can write to complement them. After using the entity object editor to define the entity object's attribute names, datatypes, lengths and precisions, associated database columns, updatability, default values, format masks, translatable prompts, and other aspects, the framework enforces these features at runtime. It automates the saving of any changes to your business entity's data in memory back to the database when the transaction is committed. You can also declaratively populate primary keys from a database sequence, maintain history columns to audit who created or modified an object and when, and enforce role-specific security access on attributes.

A simple example of code you can write on your entity object might be a create() method to provide dynamic default values to some of the entity object's attributes. In Oracle Forms, you'd accomplish this task by adding a WHEN-CREATE-RECORD trigger to your data block. With your Oracle ADF entity object, you override its create() method and add custom defaulting logic after calling super.create() to perform the default behavior, as shown in Listing 1.

Code Listing 1: New create() method

public void create(AttributeList al) {
super.create(al);
// Set Hiredate attribute to current date, without time
setHiredate(new Date(Date.getCurrentDate()));
}

Another example of code you might write is an attribute validation method to ensure that your entity object's Hiredate attribute is a date in the future for newly created employees. In Oracle Forms, you would accomplish this by adding a WHEN-VALIDATE-ITEM trigger. In Oracle ADF entity objects, attribute validation methods have a name that begins with the prefix validate , accept a parameter of the right datatype for the attribute being validated, and return a boolean value indicating whether the validation succeeded. A simple example of the Hiredate validation might look like the code in Listing 2.

Once you've written the validation method in your entity class, you enable its automatic triggering at runtime in the Validation panel of the entity object editor, selecting the Hiredate attribute and adding a new method validator based on this method. When you attach a method validator, you define a validation error message users will see when the rule is violated. These messages are managed for you by Oracle JDeveloper in the entity object's message bundle.

If a validation involves multiple attributes or related entity objects, you need something that's the Oracle ADF equivalent of a Forms WHEN-VALIDATE-RECORD trigger. In such a case, you write a validation method that takes no arguments, like the method in Listing 3, which validates that an employee's termination date comes after that person's date of hire.

When you go to the Validation tab to add a method validator for this more complex validation, you select the entity itself in the tree instead of a specific attribute. If you find yourself writing the same validation methods multiple times in several different entity object classes, using Oracle ADF you can define reusable, parameter-driven validation rules to augment the set of supplied rules. At runtime, if any of your entity object's validation rules fail, users automatically see your validation error messages on the pages where they've submitted the data in error.

Next Steps

Unique Features of Framework- Based Development

Because the Oracle ADF framework is itself implemented in Java, using Java inheritance is not only possible but also quite straightforward when you want to extend the basic functionality of the framework or globally change the default behavior to be more like what your organization needs. In other words, rather than waiting for Oracle to implement your enhancement request, you can implement it yourself in a class that extends the appropriate base Oracle ADF framework class. In practice, most development teams using Oracle ADF create a layer of classes that extend each of the base ADF framework classes and then configure Oracle JDeveloper's Business Components Base Classes IDE preference to use their customized framework base classes instead of the Oracle ADF default class names. After this one-time setup, Oracle JDeveloper adheres to your base class preferences whenever you use an Oracle ADF editor.

Consider the task of extending the Oracle ADF entity object class to add a new feature allowing you to conditionally force the value of any String-value attribute to be uppercase. Listing 4 contains the BaseEntityImpl class, which lives in your com.mycompany.fwkext package, extends the base Oracle ADF EntityImpl class, and overrides the framework method that is invoked when any entity attribute value is set.

Before calling the super.setAttributeInternal() method to perform the default functionality of assigning the new value to the attribute, this customized version of the setAttributeInternal() method in Listing 4 tests for the presence of the upper custom property on the current attribute. If the current entity object attribute has this custom property set, the customized code converts the new value to uppercase before calling the superclass.

Even if you initially have no need to extend the Oracle ADF framework, just setting up the layer of framework extension classes enables you to add code to those classes anytime—to work around a bug you might encounter or to implement a new or augmented framework feature—without having to revisit all of your existing applications.

Conclusion

Now that you have a basic understanding of how a typical Oracle ADF application is organized, what kind of code you'll be writing to implement business logic, and why developing with a framework-based approach offers new flexibility due to inheritance, you are ready to try building a simple Oracle ADF application. You'll find links to starter tutorials and our popular Oracle ADF Workshop at the Oracle JDeveloper home page on OTN.

Steve Muench is a consulting product manager for Oracle JDeveloper. In his more than 15 years at Oracle, he has supported and developed Oracle tools and XML technologies and continues to evangelize them. He authored Building Oracle XML Applications (O'Reilly Media, Inc., 2000) and shares tips and tricks on OTN and his " Dive into BC4J and ADF" Weblog.