Yesterday, Thursday May 26th, AMIS organized another of its AMIS Queries. These sessions usually bring together a substantial number of top Oracle & Java Developers from The Netherlands. This session assembled over 30 developers, from most well known Oracle and Java consultancy firms. The agenda covered the following topics:
- ADF Binding Framework – Decoupling Model and View/Controller (by Lucas Jellema)
- Working with WebServices in ADF Business Coponents (by Sandra Muller)
- JHeadstart 10.1.2 – June Patch Release New Features (by Peter Ebell)
- Dinner – on our sun-baked terrace
- Really Customizing the look and feel of Oracle ADF UIX applications (by Steven Davelaar)
- Workshop on all of the above areas, including a preview of the new JHeadstart release
Unfortunately, Steven had to cancel because of unfortunate personal circumstances. Peter and Sandra, both of the same Oracle JHeadstart team, stepped in for him.
In addition to the presentations and demonstrations, we had a some discussion, from people new to ADF and JHeadstart as well as somewhat more seasoned developers. Hot debates continue to rage over “how proprietary is ADF (for example in view of JSR-227)”, “What is the future of JDeveloper? Shouldn’t Oracle create an ADF Plugin for Eclipse”, “How well can ADF at the present be used by non-experienced developers; drag and drop is all very well, but how far does it take you in terms of real applications”, “(How) will UIX evolve into ADF Faces and will ADF Binding Framework’s integration with ADF Faces be better than the integration with UIX”. And: “should not (and will not) the functionality offered by JHeadstart be part of the ADF core run-time library as well as the Design Time IDE (generation capabilities)”. “When will we see JDeveloper 10.1.3? And what will 10.1.3 mean for JHeadstart”.
ADF Binding Framework
In the first presentation, I tried to introduce the concept of a Binding Framework, the heart of ADF in my view. The presentation focused on decoupling Model from View/Controller, trying to achieve: View unaware of Model, Model unaware of View and Controller unaware of specific Model implementation. It was my ambition to demonstrate how I could swap the Business Service (= Model implementation) without changing the View and Controller.
First I went into developing Business Services, one based on ADF BC technology, the other on POJOs – ordinary beans. Next I registered DataControls for these two services. I had taken care that the Services, their methods, collections and bean properties/ViewObject Attributes all had the same names.
Then I created three applications: a ADF JClient application, a Struts/JSP application and a simple command line Java program. Each application has its own UI Model, based on one set of DataControls, implemented by the POJO Business Service. I demonstrated the actual running of each application.
The pivotal point in the presentation: I want to switch from the POJO Business Service to the ADF BC Business Service. I changed an iterator property in each of the three UI models of the three applications. That was all it took to change over from POJO to ADF BC: I could now run the three applications, still using the same set of DataControls (or at least same name, same type) now provided by a different business service. To me, this was ultimate proof of the decoupling I was looking for. I could have Webapp-developers work on the Struts/JSP application, possibly even against a Mock Business Service, while developing the real Business Service with another team. Role separation is real option here.
I concluded the presentation with a number of Questions and Positions, such as:
How (well) will ADF Faces and ADF Binding Framework work together?
What will happen with JSR-227
Will there be development of more (advanced) DataControl Adapter classes
–For Hibernate, Spring Framework, TopLink
Will there be ADF Binding Framework (JSR-227) plugins for Eclipse?
Will the IDE be enhanced in 10.1.3?
What is the take-up in the market for ADF?
ADF Binding Framework effectively decouples Model from View & Controller
–Allowing for clear roles in development projects
ADF allows for quick first steps in application development, while respecting MVC
The typical “next steps� are still quite complex
–Especially for non-J2EE Web Developers
ADF can only be used with JDeveloper 10g
ADF is somewhat sparse for non-BC services
–Even support for Oracle TopLink is limited
Integration between ADF and UIX is not always optimal
ADF is part of the strategical tool-stack for Oracle Apps
The presentation can be downloaded here: 26may_adfjheadstart_intro.ppt
ADF and WebServices
Sandra presented on the use of WebService in combination with ADF Business Components. The business case at hand was a situation where two databases were on different sites and contained a table that had to be synchronized. This synchronization must be done through a WebService – being non-vendor specific, non-technoology specific. Sandra approached this challenge with ADF BC and WebServices. She created ViewObjects on the tables in both the Source and the Target Database. Let’s call the SourceVO (where changes originate from) and TargetVO (where data is sent to).
She created a method getSourceXML() in the source application module that returns an XML Element that contained the source data, acquired from the SourceVO using the writeXML() method. This method is published on the Client Interface of the Application Module. Next she used the Remotable Interface tab to create a WebService based on this getSourceXML() method. This WebService was subsequently deployed on a stand alone OC4J instance as SourceXMLWebService.
In the target project she created a Synchronizer class that implemented a readXML() method that takes a piece of XML as input. This method acquires an Application Module, finds the targetVO ViewObject and writes the XML to the targetVO ViewObject using the (standard) readXML() method on the ViewObject. Next she created a WebService Java Client (Stub) for the SourceXMLWebService. Then she added code to this WebService Client that invokes the Synchronizer class.
Now when the WebService client is called, it invokes the SourceXMLWebService. The piece of XML with all the data from the source table is now passed to the Synchronizer object’s readXML() method that writes this data to the target table through the readXML() method on the ViewObject.
In addition, Sandra showed briefly how you can register a WebService as DataControl and bind this data control to an ADF Struts DataPage. Thus, you can create a simple application that invokes a webservice and displays the result – without any programming!
She published her demo and workshop on the JHeadstart Blog: How-To Web Services with ADF document
JHeadstart New Features
Peter Ebell from the Oracle JHeadstart Team presented a preview of the new features, to be released in the June Patch Release for 10.1.2. Note that this release will be published on the so-called Supplement Option, only to licence-holders; it will not be made generally available on OTN. The JHeadstart team has also published a blog on these new features Cool New Features in Upcoming JHeadstart Release!. Peter was able not only to talk about these new features, he could also demonstrate them as most of them are already functional.
The first one was not even mentioned by Peter. It is the fact that in the Application Navigator we previously always found JHeadstart specific files under the Miscellaneous node, while now they appear as:
Peter demonstrated a length the extensive support for Authorization. JHeadstart works with its own User Object. This object will be loaded – by a Servlet Filter – into the session scope under a specific key. The object implements a very simple interface with nothing more than the method hasAccess(‘the thing – role or field or button or whatever – that you want to know if the user may access it’). Peter demonstrated a default implementation of this object that relies on standaard JAAS user and roles.
We can declaratively make groups and even individual buttons and fields accessible to users depending on the circumstances. Usually, these circumstances are the user logged in and the roles that user may have. However, the readOnly property of individual fields is governed by an EL Expression set on the ViewObject Attribute; this EL Expression may refer to the jhsUserRoles object but can also refer to any binding object or session or request attribute. You can use this facility to for example prevent updating of the ship date of an order when the status of the order is ‘shipped’. Peter also showed a Service Level property that can be used to define an EL expression for the entire application to set readOnly for every item; this can be used to support Viewer-mode; even though the application has facilities for manipulating data, when in viewer-mode, all fields are read-only. Note that Tabs for Groups a user is not allowed to see can be hidden from the Tabbar.
Another feature that is very simple to use – in fact, you get it automatically and have to manually switch it off – is support for Bread Crumbs. Bread Crumbs show the path the user has traversed to get to the current page. They will be supported for both UIX and JSP. JHeadstart 9.0.5 used to have breadcrumbs, though UIX only and static. The new bread crumb support is pretty clever: you include context in the bread crumb (for example Search Employees > Employees > Edit Employee Scott > Subordinates from Scott) The bread crumbs will be collected across complex navigations; for example if a group is nested for many levels, the bread crumb path will be built for all these levels. Bread crumbs cannot cycle: as soon as you visit a page that you had already visited, the previous visit and the path before that is removed from the bread crumb history.
Peter showed us several Search enhancements. The advanced search region now includes radio buttons ‘Result matches all conditions’ and ‘Result matches any condition’ with translates to AND or OR conditions used in the SQL query that is constructed based on the search fields. A button to clear the search fields is now generated as well. The quickSearch (in UIX at least) has been made a lot smarter: when you select an item to search on from the quicksearch-poplist with search items, the display type of the selected item will be set as it is in the page. For example if you select to search employees on deptno, and you have specified that deptno is displayed as a choice with department name as label (and the deptno as value), you will now get that same choice in the quicksearch. The same goes for items with LOV, Calendar Window etc.
Some enhancements were made in the area of trees (UIX only): the top-nodes in a tree can now be queried using a search. You can use the quick/advanced search features to limit the number of rows queried for the top level group of a tree. Peter demonstrated another neat feature: you can configure JHeadstart to not automatically collapse the tree when one of the nodes has been updated. Frankly, I think that should be the normal behavior so I do no regard this so much as a new feature, more a fix. Peter explained that you should only use this feature if the page does not allow changing the parent node of a selected tree node. If editing a node may include updating the parent-node, you should not disable tree collapse, as the results are somewhat impredictable.
Some new features for Table-style pages: Client-side required fields check in UIX table: When editing or creating new rows in a UIX table, a javascript alert wil be shown if required fields are empty, similar to the existing single-row required field check. Table changes no longer lost:When scrolling through table ranges, or using table detail disclosure, outstanding changes will no longer be lost. Nested child tables (in detail disclosure):A layout that has a parent “Table” group with “Table” child group(s) on the same page can give a rather unintuitive user interface, because it is sometimes not clear that the table(s) at the bottom of the page are synchronized with the selected row of the first table. We can now generate an alternative layout for this situation, where the child table is shown in the detail disclosure of the selected parent table row. As this child table can itself contain a detail disclosure, this theoretically allows for unlimited nesting of table groups on the same page.
Summer Night Dinner Party
Somewhere during Peter’s demonstration did we go down onto the terrace where we had a glorious summernight dinner with great food and a popsicle to top it off. Great atmosphere, nice people and plenty to talk about, made it worthwhile interrupting Peter’s presentation for.
Customizing the look and feel of UIX applications – Skinning
Sandra did the last presentation, on customizing the look and feel of UIX applications. Immediately after doing her presentation, Sandra posted an article on the JHeadstart blog that describes most of what she presented and demonstrated on: UIX Skinning
Sandra pointed out that there are three levels of UIX customization:
- Extending the UIX Stylesheet to customize things like fonts, colors and background image
- Define your own base set for UIX to generate graphics from, such as tab bars, global buttons, content containers.
- Change the appearance and location of default UIX components, for example change the pageLayout component to render the tab bar on the left side of the page instead of on top.
Level 1 is unavoidable it seems when you build UIX applications. This is how you apply your own organization’s web-style – primarily colors – to the application. Level 2 is much more complex. It would require somewhat serious use of PhotoShop or some design tool, to produce images for example for: left side of tab, right side of tab, middle of tab, overlap of selected tab to unselected tab, and so forth. UIX will use these images (gif files) to generate on screen graphics.
Level 3 is quite intriguing. UIX allows you to define your own renderes. That means that you define a template for rendering a UIX element. In this template – also composed from UIX elements – you can make use of all properties that are set in the UIX file on the element whose rendering you are overriding. The effect of a custom renderer is that whenever UIX is about to render the element, your own renderer is invoked. For this to happen, you do nothing in your UIX pages. You only need to configure your renderers in a look-and-feel.xml configuration file, introduce that file in the uix-config.xml file and set the look and feel of your application to the one defined in this laf file. This Inversion of Control is somewhat reminiscent of Tiles (Apache, often used in conjunction with Struts).
The overall effect of these three levels of customization that Sandra demonstated was quite dramatic. The resulting application was definitely not your typical Oracle BLAF application, even though the UIX pages were still the ones generated by JHeadstart. Therefore it is safe to say that ‘it does not look and feel the way I want it to’ is no longer an excuses for not using UIX!
Sandra prepared a small workshop, that can be downloaded here: tutorial-laf.zip. It can be applied for example to the application that is created by working through Steve Muench’s JHeadstart tutorial, which you can find here: Building J2EE Applications with Oracle JHeadstart for ADF
Workshop
The presentations and demos lasted us to well after 9 PM. Although the workstations were prepared for workshops on each of the four presentations, most people decided to have another cup of coffee or soda and call it a day. Well before 10PM the building was quiet again.
I think it is safe to conclude that the audience was pretty satisfied with the contents of the presentations. Most people went home with a lot of ideas to apply in their own work. There was a lot of fresh inspiration to start or continue working with ADF, UIX and JHeadstart.
One of the atttendants, Wilfred van der Deijl, wrote a blog with his own report: Attended AMIS Query about ADF and JHeadstart
ADF, just like BC4J, is a piece of shit. The documentation is almost non existent and sometimes the code does the opposite the documentation says. Another piece of bloatware.