I'm this week in Switzerland and can enjoy winter weather - snow paradise:
Monday, November 30, 2009
Thursday, November 26, 2009
Versioning Navigator in JDeveloper 11g R1 PS1
Just a quick note about Versioning Navigator in JDeveloper 11g R1 PS1 - its not removed, it still here ;-). If you will not be able to find it, you should keep in mind that it is moved now to View -> Team -> Versioning Navigator menu:
Wednesday, November 25, 2009
CRUD Operations in Oracle ADF 11g Table Using PopUp Component
I was blogging on previous week about how to implement CRUD operations in table component using external dialog framework (new feature in JDeveloper 11g R1 PS1) - CRUD Operations in JDeveloper/ADF 11g R1 PS1 Table Component. I got several questions from my readers about how to catch dialog Cancel event when using inline windows through external dialog framework. However, there is no Cancel Listener available for external dialog framework in this release, so its not possible to catch Cancel event. In some specific use cases it can create problems, because we want to execute Rollback when user is closing dialog by pressing Cancel button. On other hand, af:popup component have Cancel Listener, today I will show how you can use af:popup for CRUD operations in Oracle ADF 11g table.
Download updated sample application - TableDialogEdit2.zip, this sample based on my previous post mentioned above. The key difference is that now I'm using af:popup to show currently edited or newly inserted record. Editing case:
Data is edited and changes are commited to database using OK button:
If user would press Cancel, (X) or Escape keyboard button - Rollback action would be triggered. Same applies when inserting new record:
If we will take a look into source code, we will see that I have created af:popup and this component is opened through af:showPopupBehavior operations declared for Insert and Edit buttons:
Popup component itself is defined with lazyUncached content delivery and two listeners - PopupFetchListener and PopupCanceledListener:
First one is invoked during popup opening and is used to trigger Insert mode when it is needed. And second is triggered when user wants to dismiss editing dialog. Editing dialog is based on DialogListener, where Commit or Rollback operations are called:
The main trick with af:popup component usage is on Insert. The problem is, when you define af:showPopupBehavior, framework will not execute Action or ActionListener defined for the same button. So, I'm calling CreateInsert operation from PopupFetchListener, during that moment when popup is rendering. This allows to make it work for Inserts through af:popup component. Additionally, I'm doing a check there and invoking CreateInsert operation only when Insert button was pressed and not when Edit:
DialogListener invokes Commit or Rollback operations based on user action:
PopupCanceledListener is extremelly helpful and is triggered when user is closing dialog with (X) or Escape keyboard button:
Download updated sample application - TableDialogEdit2.zip, this sample based on my previous post mentioned above. The key difference is that now I'm using af:popup to show currently edited or newly inserted record. Editing case:
Data is edited and changes are commited to database using OK button:
If user would press Cancel, (X) or Escape keyboard button - Rollback action would be triggered. Same applies when inserting new record:
If we will take a look into source code, we will see that I have created af:popup and this component is opened through af:showPopupBehavior operations declared for Insert and Edit buttons:
Popup component itself is defined with lazyUncached content delivery and two listeners - PopupFetchListener and PopupCanceledListener:
First one is invoked during popup opening and is used to trigger Insert mode when it is needed. And second is triggered when user wants to dismiss editing dialog. Editing dialog is based on DialogListener, where Commit or Rollback operations are called:
The main trick with af:popup component usage is on Insert. The problem is, when you define af:showPopupBehavior, framework will not execute Action or ActionListener defined for the same button. So, I'm calling CreateInsert operation from PopupFetchListener, during that moment when popup is rendering. This allows to make it work for Inserts through af:popup component. Additionally, I'm doing a check there and invoking CreateInsert operation only when Insert button was pressed and not when Edit:
DialogListener invokes Commit or Rollback operations based on user action:
PopupCanceledListener is extremelly helpful and is triggered when user is closing dialog with (X) or Escape keyboard button:
Tuesday, November 24, 2009
Integration in Oracle ADF with ADF Task Flows and ADF BC Imports
Inspired by a question about LOV reusability from one of my readers, I decided to post one more blog in integration series. Today I will refactor application and extract shared entity into common Model project, I will create shared LOV component as well. You can read my previous postings for the same topic from this blog - Building and Integrating Oracle ADF 11g Applications with OjDeploy Utility. I will describe how you can reuse your Model components from shared projects using ADF BC Import functionality (Import Functionality in Oracle ADF BC).
Download updated application - ADFIntegration6.zip. This sample contains one more project - CommonModel. It contains shared EO for Department and one LOV VO.
Originally, I had following Model structure for LocalApp application:
And following Model for RemoteApp application:
Let's say I got a requirement to join Employees VO in RemoteApp with Department table and declare LOV component on DepartmentName attribute. This means I need to have Departments EO available in RemoteApp. However, I already have this EO in another LocalApp application, if I will create again in RemoteApp it will be duplicate. This means I should extract Departments EO from LocalApp into common project and use it through ADF Library JAR import. I have created common Model project and declared Department EO there along with LOV component for Departments:
I deploy CommonModel project into ADF Library JAR as it is described in my post above and import it into LocalApp through Business Components Imports:
Now I can remove Departments EO from LocalApp Model and use it through imported library. You can see that Departments EO is included now from com.redsamurai.model package:
The same for RemoteApp project, I have included there same ADF Library JAR:
And I can use shared Departments EO in Association relationship between Departments and Employees EO's:
Probably you already noticed that LOV component is imported together with EO:
Then I can use it while declaring LOV for DepartmentName attribute:
Finally, before running my application, I will update its skin setting to fusion. My original application was developed with previous JDeveloper release, however I want to use new skin, I can change it trinidad-config.xml file:
On runtime I can see Employees table joined with Departments and DepartmentName LOV column rendered:
Download updated application - ADFIntegration6.zip. This sample contains one more project - CommonModel. It contains shared EO for Department and one LOV VO.
Originally, I had following Model structure for LocalApp application:
And following Model for RemoteApp application:
Let's say I got a requirement to join Employees VO in RemoteApp with Department table and declare LOV component on DepartmentName attribute. This means I need to have Departments EO available in RemoteApp. However, I already have this EO in another LocalApp application, if I will create again in RemoteApp it will be duplicate. This means I should extract Departments EO from LocalApp into common project and use it through ADF Library JAR import. I have created common Model project and declared Department EO there along with LOV component for Departments:
I deploy CommonModel project into ADF Library JAR as it is described in my post above and import it into LocalApp through Business Components Imports:
Now I can remove Departments EO from LocalApp Model and use it through imported library. You can see that Departments EO is included now from com.redsamurai.model package:
The same for RemoteApp project, I have included there same ADF Library JAR:
And I can use shared Departments EO in Association relationship between Departments and Employees EO's:
Probably you already noticed that LOV component is imported together with EO:
Then I can use it while declaring LOV for DepartmentName attribute:
Finally, before running my application, I will update its skin setting to fusion. My original application was developed with previous JDeveloper release, however I want to use new skin, I can change it trinidad-config.xml file:
On runtime I can see Employees table joined with Departments and DepartmentName LOV column rendered:
Monday, November 23, 2009
Tree Table Component in Oracle ADF
I want to share today, how we are using Tree Table components in Oracle ADF. Sure, you can implement Tree or Tree Table just by reading Oracle JDeveloper 11g documentation. However, I will try aggregate different information and to put all pieces together, in order to help those developers who are just starting to use Tree components and are curious how things work. My today post is based on information from Frank Nimphius article available on ADF Code Corner - How-to access the selected row data in a TreeTable or Tree.
Download sample application developed in JDeveloper 11g R1 PS1 - TreeComponents.zip. In this sample I'm using two Tree Table components, second is dependent on first. Dependency could easily work through View Link Master-Detail relationship, but I decided to make use case a bit more complex and to filter second Tree Table from Selection Listener method. Also, I decided to include editable fields into both Tree Table components.
First Tree Table represents three level Master-Detail relationship between Regions, Countries and Locations. Second Tree Table is Master -Detail between Departments and Employees:
Its worth to mention, that Departments VO contains Bind Variable and Where clause, this allows me to filter second Tree Table from first Tree Table Selection Listener method:
On the layout side in ViewController, I have used Panel Dashboard (new component in JDeveloper 11g) - it allows to align your panels with Tree Table components in very easy and elegant way:
When you decide to create Tree or Tree Table, you should drag and drop from Data Control only Master VO. From a wizard you can add Tree Levels (VO details) and specify attributes to be shown on each level:
When Tree Table will be generated, if you want to have multiple columns, you should add Column components manually and define output/input components manually. Make sure you are assigning correct values from node binding (see my sample application):
Second Tree Table is refreshed based on selection changes in first Tree Table, this means we should declare Partial Trigger dependency:
We override default Selection Listener on first Tree Table in order to perform filtering on second Tree Table component:
In Selection Listener I'm using Java code from Frank Nimphius article mentioned above. I'm accessing currently selected row and if this row belongs to third level (Locations), I'm filtering second Tree Table:
On runtime you can see how nicely Panel Dashboard allocates two Tree Table components in Panel Boxes:
Expanded Tree Table view, with editable columns:
Download sample application developed in JDeveloper 11g R1 PS1 - TreeComponents.zip. In this sample I'm using two Tree Table components, second is dependent on first. Dependency could easily work through View Link Master-Detail relationship, but I decided to make use case a bit more complex and to filter second Tree Table from Selection Listener method. Also, I decided to include editable fields into both Tree Table components.
First Tree Table represents three level Master-Detail relationship between Regions, Countries and Locations. Second Tree Table is Master -Detail between Departments and Employees:
Its worth to mention, that Departments VO contains Bind Variable and Where clause, this allows me to filter second Tree Table from first Tree Table Selection Listener method:
On the layout side in ViewController, I have used Panel Dashboard (new component in JDeveloper 11g) - it allows to align your panels with Tree Table components in very easy and elegant way:
When you decide to create Tree or Tree Table, you should drag and drop from Data Control only Master VO. From a wizard you can add Tree Levels (VO details) and specify attributes to be shown on each level:
When Tree Table will be generated, if you want to have multiple columns, you should add Column components manually and define output/input components manually. Make sure you are assigning correct values from node binding (see my sample application):
Second Tree Table is refreshed based on selection changes in first Tree Table, this means we should declare Partial Trigger dependency:
We override default Selection Listener on first Tree Table in order to perform filtering on second Tree Table component:
In Selection Listener I'm using Java code from Frank Nimphius article mentioned above. I'm accessing currently selected row and if this row belongs to third level (Locations), I'm filtering second Tree Table:
On runtime you can see how nicely Panel Dashboard allocates two Tree Table components in Panel Boxes:
Expanded Tree Table view, with editable columns:
Thursday, November 19, 2009
Building and Integrating Oracle ADF 11g Applications with OjDeploy Utility
While attending Steve Muench session on OOW'09 I learned about Oracle Fusion Applications Teams' Best Practices. One of the things I was very interested - ojdeploy utility usage in automatic builds. In our project, we are building and maintaining custom Ant scripts to generate EAR file and to deploy it to WLS. However, it creates a lot of extra work, especially while migrating from one Oracle ADF release to another. Some customers are considering to use Maven Integration in JDeveloper 11g R1 PS1 (see article) for integration builds. But, while designing your integration build architecture, you should not forget about powerful ojdeploy utility offered by Oracle and shipped together with JDeveloper 11g. From my point of view, main strengths of ojdeploy are the following:
- You can build deployment package directly from command line, same as it would be build using JDeveloper 11g wizards
- Oracle ADF library references are resolved automatically, this means you dont need to maintain complex Ant scripts
For today post I have decided to use application from my previous post - Integration in Oracle ADF with ADF Task Flows and Shared Java Classes. I have created ojdeploy script for this application, you can download complete sample - ADFIntegration5.zip. More info about ojdeploy utility you can find from Steve Muench blog post.
Sample application is based on 3 applications, one of them is main application. First are build two dependent applications and then EAR file is produced based on main application. In the script you need to point to appropriate deployment profiles to be invoked for each application:
Invoke ojdeploy utility from command line (ojdeploy -buildfile ojdeploy-build.xml) and all three applications will be compiled and packaged automatically:
EAR and WAR files are generated for main application, along with ADF Library JAR files for dependent applications:
In order to build and integrate my application, I have defined following deployment profiles:
ADF Library JAR deployment for first dependent application.
ADF Library JAR deployment for second dependent application.
WAR deployment profile for main application.
EAR deployment profile for main application.
Tuesday, November 17, 2009
CRUD Operations in JDeveloper/ADF 11g R1 PS1 Table Component
While working on the customer side during last week, we have discussed a use case where user works with read-only tables and performs data editing through inline popup. In ADF 11g you can use clickToEdit editing mode for a table component in order to improve rendering performance. With this mode table will be rendered as read-only, but user will be able to edit rows by double clicking on current row. However this case was not suitable for the client, they wanted to edit and insert new rows in inline popup, mainly because there will be additional editable columns. We have tried to implement this requirement in JDeveloper/ADF 11g R1, using af:popup component, but it was not working for insert mode. Same week we got new Oracle JDeveloper release - JDeveloper 11g R1 PS1, and new functionality that allows to open ADF Task Flows as inline popups (read Frank Nimphius blog post - JDeveloper 11g R1 PS1 New Feature: Launching DHTML popup dialogs using the external dialog framework). In this blog post I will describe how you can enable CRUD operations in table component using ADF Faces external dialog framework.
Download sample application with implemented CRUD functionality - TableDialogEdit.zip. This sample provides a table component, with implemented Insert, Edit, Save, Delete and Undo functionality:
Table is read-only, Insert and Edit operations will be performed through inline dialog. User can select a row and by pressing Edit, will open a dialog to edit data:
When user will press Close button inside inline dialog, Dialog Return Listener method will be invoked to refresh parent table, see code in managed bean. Data in parent table is refreshed, user can commit his changes by pressing Save button or revert by pressing Undo:
In similar way, user can create new row by pressing Insert, blank row will be opened in inline dialog:
User can insert data, and close inline dialog with Close button:
Previously inserted blank row will be refreshed with entered data, same as in editing case user can commit or revert it:
I have implemented this functionality based on information from Frank Nimphius blog mentioned above. From main page located in ADF Unbounded Task Flow, I'm calling ADF Bounded Task Flow where editing JSPX page is implemented. If Insert button was pressed, before calling ADF Bounded Task Flow, CreateInsert operation Method Call is invoked:
Call for ADF Bounded Task Flow is defined to run as dialog and to be displayed as inline popup:
This allows us to open standard ADF Bounded Task Flow as inline dialog:
On the main page, table panel collection contains five buttons, two of them - Insert and Edit are opening inline dialog for data editing:
Those two buttons should be configured to open inline dialog, by setting UseWindow, WindowEmbedStyle and WindowModalityType properties accordingly: