Monday, October 15, 2007

Oracle Fusion Middleware Workshop in Vilnius

Today I was on Oracle FMW (Fusion Middleware) Workshop in Vilnius, actually it was a workshop based on my material available in Oracle Fusion User Group (OFUG). There were 22 people auditory, at the beginning I have presented information about Oracle ACE Directors, Oracle Fusion Middleware, Oracle JDeveloper with ADF, and Technical Resources needed to start to work with Oracle JDeveloper and ADF. Presentation took for me about 1 hour, after it people started to solve labs. There were six labs, all of them are available in OFUG for free to download. During labs solving, there were quite many questions about ADF, I was glad to provide answers. At the end I realized, that while answering questions, I got even new knowledge for me. Thanks for great auditory!



Tuesday, October 9, 2007

Using Hidden Column in af:table Component

Quite often you may face requirement, when you will need to use hidden column in af:table component. Such requirement could be to insert into database, along with values provided by the user, some another value automatically. This value is not visible for the user and is inserted through a hidden column. Hidden column here should be understood as a column that doesn't exist in af:table component, but exists it's definition in page definition file for associated table.

Developed sample application - HiddenColumn.zip provides JSPX page with a table component, that allows to create new data for Employees entity. Five columns are available in the table - First name, Last name, Email, Hire date and Job Id. But along with data for those five columns, data for Salary column is stored into database as well. Value that is inserted into Salary column is retrieved from Resources.properties file. Now I will describe how actually data is inserted into a column, that is not available in af:table component.

First step is to use the same technique, which I have successfully used in my previous samples - to include managed bean method call into let's say ReadOnly property of any column available in the table. In developed sample application, I have included #{valueHolder.readOnly} into ReadOnly property of First name column. This technique allows to invoke managed bean method, when each row of af:table component is rendered. Managed bean method code:


Developed method always return false value, it is because we always want to have editable column and are using this method for other purpose. Method is used to set Salary value #{row.Salary} for newly created row. Row is determined as a newly created using #{row.EmployeeId}. If DBSequence value is negative this means that row is newly created and we set value for #{row.Salary}.

Let's say we create new row and provide values for all columns:


When Save button is pressed, new row is inserted into database. Value for Salary column is inserted as well:


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

Wednesday, October 3, 2007

Conditional rendering of JSF fields based on dynamic af:selectOneChoice

My friend in her recent project was implementing conditional rendering of JSF fields based on dynamic af:selectOneChoice component, and she was in trouble with this. There exists excellent Grant Ronald blog post - Conditional rendering of JSF fields depending on a drop down list (af:selectOneChoice). However, Grant in his post describes conditional rendering of JSF fields depending on fixed drop down list, not dynamic. Together with my friend we have developed needed solution and I have decided to post it.

Sample application - DependentDBList.zip is based on standard HR schema and provides one JSPX page called main.jspx. This page contains form component with navigation controls and functionality that allows to create new data and save changes in existing one. Application is focused on two form elements - DepartmentId and PhoneNumber. Functional requirement is not to show PhoneNumber element if IT is selected in DepartmentId drop down list.

Probably you will ask, what is the difference between fixed and dynamic drop down lists in conditional rendering. In fact it is similar, however you will need to add some Java code. Steps are the same like described in Grant Ronald blog I have mentioned, however implementation of some steps differs. Here I will describe differences.

At first you need to create dynamic drop down list for DepartmentId, this step is simple. In developed sample application for List Iterator is used DepartmentsView1Iterator, this iterator binds to DepartmentsView1 data control. We will need to access created drop down list to get selected value, to make it possible we have created table definition and binded it to the same DepartmentsView1Iterator iterator. Don't forget to enable AutoSubmit and set PartialTriggers on parent UI item.

PhoneNumber element property Rendered we have binded to a method available in page backing bean, this method is called - isPhoneNumberRendered(). Method code:


Code is straightforward but it allows to use dynamic drop down list in conditional rendering. In this code, DepartmentName is retrieved for selected element in drop down list, and it is compared with IT department. Depending on comparison result, true or false is returned and based on returned value component is rendered or no.

Here PhoneNumber is shown:


And when IT is selected for department, PhoneNumber is not shown. It will not be shown even if you will just open a page with IT department 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, September 30, 2007

Sofia - Beautiful City

On this week I was visiting Sofia, Bulgarian capital. City is a mix of western and eastern culture, this makes it unique and beautiful. Definitely you should find time to visit it, you will have a chance to meet very warm and friendly people ;).

St. Alexander Nevsky Cathedral, it was built in honour to the Russian soldiers who died during the Russo-Turkish War of 1877-1878. It looks really impressive.

Friday, September 14, 2007

Automatic Java class invocation after deployment of Oracle ADF application

Recently I was implementing requirement of automatic Java class invocation right after application is deployed on Oracle Application Server. Automatic class loading possibly is required when for example job scheduling system like Quartz is used by application. This means that job scheduling should be started right after application is deployed, so main question is how to to invoke Java class automatically.

In developed sample application - DeploymentRegistration.zip, I have decided not to use any job scheduling invocation, but to implement deployment registration functionality. Implemented logic - when application is deployed, record with history data is stored in the database table. Application itself is based on standard HR schema, however some additional elements are used. You can find SQL script with statements for database table, sequence and trigger in sample application package.

Data is inserted into database table using application module that is looked up and created using a Command-Line Java Test Client for ADF BC. So, this means that ADF BC functionality is accessed from external Java class. Java class code, which is invoked automatically after deployment:

DeploymentHistory class acquires application module, creates new row and commits it into database. You are probably interested, how this code is invoked automatically, after deployment. Automatic invocation is implemented using simple servlet - AutoLoader, this servlet is loaded automatically after deployment and invokes main method in DeploymentHistory class. Servlet code:


AutoLoader servlet is declared in web.xml with load-on-startup setting equal to 1, this means that servlet will be loaded after deployment automatically and init method code will be executed. Declaration in web.xml:


Now we can test developed application. To test it we can use OC4J that comes with JDeveloper, just right-click on main.jspx and choose Run - application will be deployed on embedded OC4J and started. Developed application shows a table with information about countries and provides a button - Deployments History, which opens pop-up window with information about deployments history stored in the database.


Let's say there were several deployments, it is reflected in deployments history:


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

Wednesday, September 5, 2007

Oracle Fusion User Group and JDev/ADF Labs

We (Frans Thamura and me) have decided to open Oracle Fusion User Group (OFUG). User Group homepage - ofug-global.

OFUG is created in order to bring together technical people who are working with Oracle Fusion. This group will be focused on educational aspect, everyone could share knowledge and get benefit from acquiring available knowledge.

OFUG was created by Frans and is based on labs material that I have prepared recently. Everyone who will join OFUG, can use this material for his/her education. In October I will deliver 1 day workshop based on those labs in Vilnius for local technical community.

Currently in OFUG are available those labs:
  1. Labs environment description
  2. Data model layer development using ADF Business Components
  3. Page flow definition
  4. Search functionality development. Search page contains a form for search parameters and a table for search results
  5. Create functionality development. This page contains several select-one-choice components and allows to insert new data into Departments entity
  6. Edit functionality development
  7. Complex table component development. This component will allow to perform create, update, and delete operations
OFUG mailing list: ofug-global@yahoogroups.com

Multi-selection and Row Data Editing in ADF Faces

In this post I have decided to dive into multi-selection feature offered by ADF Faces little bit more deeper and to show how it could be used in practice. Developed application use case is based on two pages, in first page user can select multiple rows in search results table and press edit button. Second page will be opened only with selected rows. So, this post is focused on how to open in second page only rows selected in first page.

Sample application - TableSelection.zip is based on standard HR schema. Two pages are implemented - search.jspx and edit.jspx. In search.jspx you can find two components - a search form and and a table for search results. In search form is implemented af:selectOneChoice component and table contains read-only af:selectOneChoice for region names. In edit.jspx there is editable table with af:selectOneChoice component for region name.

So, what happens when in search.jspx Edit button is pressed? Edit button is binded with editButton_action() method, available in backing_search backing bean. This means, when Edit button is pressed - editButton_action() is invoked:


This method finds needed iterator and acquires keys for selected rows. And main functionality - method sets where clause for View object that is used in edit.jspx page. Where clause is generated according to primary keys data of selected rows, this allows to open in edit.jspx only needed rows.

Just imagine, that we want to move several countries to other continent - no problem, select those countries and press Edit button:


Edit form is opened, here you can change region name for selected countries, save your changes and return to search form:


And..., you can continue a process... :-)

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