Wednesday, August 29, 2007

ADF Task Flow in JDeveloper 11g

In JDeveloper 10g there is only one possibility to design application page flow structure - using JSF navigation flows. But sometimes, use cases require to implement complex page flow, that is not supported by JSF navigation flows. JDeveloper 11g brings ADF task flows in addition to JSF navigation flows. From Oracle JDeveloper 11g Technology Preview, Fusion Developer's Guide for ADF:

Task flows provide a more modular and transactional approach to navigation and application control. Like standard JSF navigation flows, task flows mostly contain pages that will be viewed. However, instead of describing navigation between pages, task flows facilitate transitions between activities. Aside from navigation, task flow activities can also call methods on managed beans, evaluate an EL expression, or call another task flow, all without invoking a particular page. This facilitates reuse, as business logic can be invoked independently of the page being displayed.

In developed sample application - ADFTaskFlow.zip, task flow is implemented for Department data editing. Sample is based on standard HR schema, available in Oracle XE Database. Application contains one JSPX page and this page is divided into two parts - in first part Locations are shown, in second part Departments are managed. Departments management requires to have two views - one for viewing and selecting, second for editing and saving. Additional requirement - to have Locations table displayed always. In JDeveloper 10g, we probably would implement such application with two pages, but in JDeveloper 11g we can use task flow functionality and implement it with one page.

In application Model layer, two entity objects are implemented - Departments and Locations. Based on those entities, View objects are generated and exposed as HrModule Data Model components.

Central role in developed application plays task flow implementation:

Task flow is available in task-flow-definition.xml file - two views and navigation cases are defined. You can define task flow components by dragging and dropping required elements to task flow diagram from Component Palette:


viewDepartments implements a table component with selection feature. When row is selected and opened for editing - editDepartments view is opened. In editDepartments you can change available data and commit it to database - viewDepartments will be opened automatically.

In order to use developed task flow, you can drag and drop it into your JSPX page. Select task flow in Application Navigator window:


When you will put it into your JSPX page, pop-up menu will be opened, where you can choose how task flow should be created:


In developed sample application, I have created task flow as Region.

And last step - JSPX page that contains a task flow, should be registered in adfc-config.xml file. In developed sample, I have just dragged and dropped main.jspx page into adfc-config.xml file:

Now we can check, how application screen look. Page contains two parts - Locations and Departments. Locations part is implemented as simple table with filtering feature, just to browse through data. In Departments part, task flow is implemented, first part of task flow - viewDepartments is shown here:


We can select any row in Departments table and open second part of task flow - editDepartment:


Edit form for Department data is opened in the same page and table with Locations is still shown - required behavior. Main advantage of task flow in this application - data for locations is always available and action can be performed in the same time. If user wants to change department location and wants to know more about new location - he/she can browse for required location in Locations table.


We set Munich city as a new location and press Save button - data is commited to database and first view of task flow - viewDepartments is opened.

Saturday, August 18, 2007

Create multiple rows in Oracle ADF

Recently I have noticed a question on OTN JDeveloper forum about how to create multiple rows in ADF Faces af:table component and insert those rows into database. Actually almost at the same time my friend asked me for help, her goal was to develop exactly the same functionality. So, it seems multiple inserts could be quite often requirement.

Developed sample application - CreateMultipleLocations.zip is based on LOCATIONS table from standard HR schema. Developed business logic allows to create several locations in specified city at once.

To make this sample more interesting, number of rows to create is specified in property file - Resources.properties. Property value available in this file is retrieved in backing bean method and specified number of rows is created respectively.

Sample application JSPX page is divided into two main areas - Panel Box and Table:


First part contains a form, this form allows to provide a city, where locations will be created. It is mandatory to provide a city name, before creating locations. What is most important - Create button for LocationsView1 is developed in the same way as it is described in my previous post - Creating new row using CreateInsert operation. In second part, editable table is created, this table allows to add and edit locations data.

I guess, you may wonder - where is a specific of multi insert. In fact, it is only in one place - in action method for Create button. Developed createButton_action() method:


In first line of this method, value from property file is retrieved. Based on retrieved value, one or multiple rows are created and inserted into View object.

Let's say we want to create several new locations in Vilnius city, so just provide city name and press Create:


Provide required data and press Save:


When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.

Thursday, August 9, 2007

Three Dependent List Boxes in af:table Component

You may already have read Frank Nimphius blog post - ADF Faces: How-to create dependent list boxes in a table. Frank describes in his blog how two dependent list boxes can be implemented in af:table component. He implements dependency between Departments and Employees from standard HR schema.

One day I have decided to implement three dependent list boxes in af:table. I thought it will be simple - have applied the same steps as Frank describes and enabled partial triggering on third list based on first and second. However, things aren't always simple - it was not working in such way. But, I have found a solution and implemented it as sample application - DependentListBoxesThree.zip.

Implemented sample application is based on standard HR schema, also the same additional table as in Frank sample is used - VACATIONREQUESTS. However, table is updated with LOCATION_ID column and foreign key is created that references LOCATIONS table. SQL script for table update you will find in application archive.

Sample is based on solution available in Frank blog, so I will describe only those things I have added to make three dependent list boxes work. I have implemented dependency between LOCATIONS, DEPARTMENTS and EMPLOYEES tables from HR schema.

Steps I have applied:

1. In Model layer implement read-only View Object - DepartmentsCheckView. This View Object will be used to check specified department availability in particular location.


2. Open Vacationrequests Entity Object edit window and select Refresh After Insert for Approved attribute.


3. In View layer, for all iterators related to list boxes dependency set StateValidation="false". This will help to avoid JBO-35007 error, this error was generated sometimes for me during sample testing. More information about this error you can find in Chris Muir blog post - Bah! What is JBO-35007.

4. The main problem was to refresh third list box, when second or first list boxes are changed. When second list box is changed, the same solution as for first and second is applied. However, when first is changed, second list changes and third list should appear empty as value in second list is not selected. For this purpose in getEmployeesSelectItems() method checkDepartmentByLocation is invoked. It accepts two parameters - depId and locId and returns 0 or 1. Returned value helps to determine how third list should be generated.


checkDepartmentByLocation method is implemented in Application Module class:


5. List box for employees is created based on EmployeesView2 from DepartmentsView1.


And now will show how it works. Three dependent list boxes:


It is possible to create new row, you can select location, department and employee from list available for selected department. Also notice, that in fourth row I have changed location from Munich to South San Francisco and you can choose department, but can't select employee as no department is currently selected:

When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.

Sunday, July 29, 2007

Web Service Invocation in Oracle ADF

Some time ago I was blogging about how to access persistence layer through Web Service interface - Web Services and Oracle TopLink. I have mentioned, that I will extend developed sample and will show how it is possible to use Web Services in Oracle ADF View layer.

Frank Nimphius have posted this week how-to article on OTN - Using Web Services with Complex Return Types in ADF. In this article, Frank describes in detail how to include and use your Web Service in Oracle ADF application. I have decided to apply described steps and develop client application - WSTopLinkClient.zip for my previously developed sample Web Service - WSTopLink.zip.

In developed client application, data retrieved from Web Service, is shown in af:table component:


Data for all three columns is retrieved from Web Service, however labels for regionId attribute are provided from client application Model layer. In Oracle ADF, data from Web Service can be easily merged with data provided by Model layer.

When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.

Saturday, July 21, 2007

Invoking BPEL Process from Oracle ADF Application

In today post I have decided to describe and show how application developed using Oracle ADF can fit into SOA (Service-Oriented-Architecture). SOA is important technology, because it allows developers to find common language with business analysts and as result to develop more useful systems. Simply speaking, SOA allows to participate in system development both parties - IT and non IT. IT folks develop technical things and non IT people are allowed to manage system logic. My goal is to show, how it looks in reality, and how it works with Oracle JDeveloper and Oracle SOA Suite. Sample applications are developed using Oracle JDeveloper 10.1.3.3 and BPEL process is tested on Oracle BPEL Process Manager 10.1.3.1.0. For those who will want to look further, I recommend to browse through Guides and Tutorials available on Oracle BPEL Process Manager 10.1.3.1.0 Information page.

Web application - SalaryBonusApplication.zip and synchronous BPEL process - SalaryBonusProcess.zip are provided as sample applications. Web application Model layer is implemented using Oracle ADF Business Components and is based on standard HR schema, in View layer ADF Faces components are used. Synchronous BPEL process access HR schema using Oracle TopLink.

Developed logic - in Web application users can search for particular employee and select him/her for salary update process. Salary update is based on current salary and applied bonus value. Salary update business logic is implemented in BPEL process. So, it's where we can see a power of SOA - salary update business logic can be changed at any time by non IT people, they will just need to modify defined process.

I will start from process part description. Implemented BPEL process diagram:


In first step, process receives input. In second step, conditional logic is applied and process output is calculated. When process output is known, data is transformed to be compatible with EMPLOYEES table structure from HR schema. After transformation step, employees data update in database is invoked and process is finished.

As it was described, salary update process is based on two parameters - current salary and applied bonus, however employee ID is also needed. Process parameters are described in XSD document:


Process logic is implemented in switch activity. Switch activity rule is based on bonus variable value:


When process output is calculated, data should be transformed in order to be stored in EMPLOYEES table. Transformation can be defined using Oracle JDeveloper wizard tool:


And finally, transformed data is used in database update through Invoke activity:


Yes, database table will be updated from BPEL process. And there is no magic, simply Oracle TopLink object-relational mapping functionality is used. Complete project structure view in Oracle JDeveloper navigator:


Process part description is completed, now we will move to Web application part. Web application contains two forms, first is Search Employees form:


Second form - Edit Employee Salary, can be opened for selected row:


Update Salary button here invokes BPEL process. Salary calculation is done outside of Web application, through Web Service submited values are passed to process where are modified and stored to database. In Web application refresh action is executed and updated values are shown:


You can notice, that salary value is increased by 100, this logic is defined in BPEL:


You may wonder, how BPEL process can be included into Web application developed using Oracle ADF. But it is simple, Oracle JDeveloper provides complete solution - you just need to provide WSDL URL and Data Control for available operations will be generated and displayed in Data Control pallette:


BPEL process is accessed through Web Service specified in DataControls.dcx file:


Action related to BPEL process is defined in page definition file in standard way:


Executed BPEL process instance can be explored from Oracle Enterprise Manager 10g BPEL Control window - executed process steps are represented in visual flow and values available in each step are provided:


When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.

Saturday, July 14, 2007

Opening Report Window in ADF Faces

Such requirement as opening report window can be assumed as easy one. But, when I have received request for solution, it was not so easy to find it :). On OTN Discussion Forum there are questions on this topic, but no clear answers. Opening report window in ADF Faces is important requirement, because quite often Oracle Reports are needed to be opened from Web application.

Requirement description:
  1. In JSPX page we have a table or form where parameters can be entered
  2. On the same page we have a button. When it is pressed, entered parameters are passed to backing bean method, where based on provided parameters URL string is generated
  3. Generated URL is opened in Web Browser new tab or window
Main question here - how to open new tab or window when button is pressed. To implement solution for this requirement, at first I have tried to use JavaScript with binded dynamic parameter for URL generated in backing bean. This solution wasn't suitable, because JavaScript is always executed one step forward comparing to backing bean Java code.

I have found another solution, it is quite simple and is implemented in my sample - ReportWindow.zip. af:commandButton doesn't have Target property, but h:form does. Submit action of af:commandButton component, placed into h:form with Target property set to _blank, is always executed in new tab or window (depends on Web Browser).

Developed sample implements two h:form components - one is used for parameters and second for button:


Second h:form component property Target is set to _blank:


JSPX page backing bean contains some dummy code for URL generating. URL is opened using ExternalContext obtained from FacesContext:


This code is executed when Open Report button is pressed, URL is generated according to submited parameters. Data available in parameters form should be auto submited, in order to be available from second form where Open Report button is implemented:


Generated URL is opened in new tab:


When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.

Tuesday, July 3, 2007

Problem with samples hosting again! (updated)

Hosting problem is solved and all sample applications are available for download. University stuff was really quick, thanks!

I have noticed today, that sample applications are unavailable for download. Sorry for that, I will fix it in short time. Thanks!

Since I'm not a student anymore, university have closed my account, but I will ask to open it again :).

Post updated: 7/4/07