Partial page submit and instant page refresh via Ajax-enabled UI components don’t, alone, guarantee a rich-client Web experience. A consistent page layout and predictable page behavior are just as important to application usability. The Dynamic Tabs UI Shell template in Oracle JDeveloper 11g helps developers give their Oracle Application Development Framework (Oracle ADF) application pages a consistent look that meets high standards for usability. The template includes prewired behavior such as programmatic tab opening and closing, tab navigation, and tracking of the transaction state for content displayed in a tab. Users gain a rich-client experience because the locations and behaviors of the application’s prominent features are consistent and predictable.
This column provides an overview of the Dynamic Tabs UI Shell template and illustrates its key concepts through a sample application. Although the sample application doesn’t implement all of the template’s public APIs, it gives you a starting point for exploring how and when to use it. The column then delves deeply into the template’s architecture to describe its full functionality and help inform your Oracle ADF programming practices.
To begin, download the sample application and unzip the file to a local folder on your computer. Ensure that you’re using the studio edition of Oracle JDeveloper 11g Release 2 (188.8.131.52) or later, available as a free download on Oracle Technology Network.
A ReadMe.doc file with setup instructions for the adf_summit database schema used in the sample is located in the dynamic-TabShellSample/Schema folder in the directory where you unzipped the sample application. After installing the adf_summit schema, open the SummitADFUIShell.jws workspace, located in the application directory’s dynamicTabShellSample/SummitADFUIShell folder in Oracle JDeveloper. Adjust the properties of the connection named summit_adf in the Application Resources zone of the Application Navigator until you can successfully test a connection to the summit_adf database schema, using summit_adf as both the username and the password.
In the Application Navigator, expand the ViewController project node and then the Web Content -> temp -> WEB-INF folder. Double-click the adfc-config.xml file to launch the Oracle ADF task flow visual diagram. In the diagram, right-click the Index view activity and choose Run to launch the application in a browser.
If you are running an application in the integrated Oracle WebLogic Server for the first time, the Configure Default Domain dialog box will appear. Enter an administrative username and password of your choice for your domain, and click OK.Sample Application Overview
The sample application manages customer and order information for a fictional seller of wholesale sporting goods. The application launches with the index page shown in Figure 1. Click the Customer Care Center link or tab to start exploring the application’s functionality. (Customer Care Center is the only option enabled; the other links and tabs are placeholders included for illustrative purposes only.)
Figure 1: Sample application start screen
The Customer Care Center module, shown in Figure 2, enables users to browse and edit customers and customer orders. At runtime, the contents of the page area that initially shows the welcome image are dynamically replaced with customer or order data that the user selects via a link, a tab, or a context menu.
Figure 2: Customer Care Center viewReusable Page Flows
Reusable page flows—known as Oracle ADF task flows—are at the heart of the Dynamic Tabs UI Shell template. Bounded task flows enable you to define reusable page navigation flows that model a specific business use case—such as the create, read, update, and delete (CRUD) operation for a customer or an order entity.
The sample application uses three bounded task flows to handle the customer and order CRUD use cases:
CustomerOrdersCRUD-btf enables users to browse and edit the orders belonging to a selected customer.
CustomersCRUD-btf enables users to edit customer accounts and create new customers.
OrderItemsCRUD-btf is referenced from the CustomerOrdersCRUD-btf task flow to edit the line items for a customer order.
Bounded task flows can be developed based on task flow templates, which you define visually and declaratively in Oracle JDeveloper and use by either direct reference or copy. Task flow templates expose the same set of properties as bounded task flows. For input parameter and navigation flow consistency, the sample application’s bounded task flows were developed based on a reusable common task flow template. The task flow template contains the configuration for a managed bean that is referenced by predefined task flow input parameters. One of the template’s input parameters is tabContext, which prepares task flows that are based on the task flow template to be used in the context of the Dynamic Tabs UI Shell template. Defining a managed bean in the task flow template to hold input parameter values enables you to expose an easy-to-discover, easy-to-use API for predefined input parameters such as tabContext.
The SummitADFUIShell application does not contain the task flow source code, referencing it instead from Oracle ADF libraries. The task flow source files reside in the dynamicTabShellSample -> ReusableModules -> BoundedTaskFlows folder, located under the main application directory. The BoundedTaskFlows folder also contains BoundedTaskFlows.jws, a workspace you can open and explore in Oracle JDeveloper.
The Dynamic Tabs UI Shell template supports applications that enable the type of multitasking that call center agents must do, such as looking at the data of the customer currently on the phone while bringing up the data of the next customer in the queue. For this purpose, the Dynamic Tabs UI Shell template leverages Oracle ADF regions, which enable bounded task flows to run isolated in specific areas of a page.
Executing bounded task flows in an Oracle ADF region requires development of task flows with page fragments that render the views—a configuration option you specify in the task flow creation dialog box. The Dynamic Tabs UI Shell template then exposes APIs that enable you to manage these regions programmatically within UI Shell tabs.Laying Out Content in the Dynamic Tabs UI Shell Template
The Dynamic Tabs UI Shell template is applied to top-level pages in an Oracle ADF Faces application. In Oracle JDeveloper 11g Release 2, a top-level page is a JavaServer Faces (JSF) 2.0 Facelets document that can be run standalone to display in a browser. You use the Dynamic Tabs UI Shell template to partition the main application page (the index page) into different functional areas, such as customer care, storefront, and shipping. Each functional area has its own top-level page that also references the Dynamic Tabs UI Shell template. With this modular architecture, you can easily assemble top-level pages into a single application.
As shown in Figure 3, the template layout is broadly organized into a header area, a main area, and a footer area.
Figure 3: Dynamic Tabs UI Shell template design
The header area contains the page logo, a branding title, and an area for placing global navigation links and search. You configure the logo and the title through template properties exposed in the Oracle JDeveloper Property Inspector feature. The link and search area are facets into which you can drag and drop Oracle ADF Faces components. These facets are simply placeholders for grouping components in a specific area of a parent component, such as a template. Facets that are left empty do not appear in the rendered page at runtime.
The template’s main area supports global and local navigation. Global navigation—that is, switching among top-level pages—is performed by global tabs (represented by the red rectangles in Figure 3). Local navigation (content added to the green area in Figure 3) launches or switches among task flows exposed on tabs in the template’s local area (the yellow rectangle in Figure 3).
To define global navigation, you add the Oracle ADF Faces af:navigationPane component to the globalToolbar facet and add af:commandNavigationItem components as child components to handle the navigation. Alternatively, you can use an XML menu model that you can create from page navigation defined in the adfc-config.xml file to dynamically render the af:commandNavigationItem instances.
The sample application has af:tree and af:table components added to the navigation facet representing the navigation area (green in Figure 3). The navigation facet enables users to navigate content exposed in the local area. The local area of the template is managed by the Dynamic Tabs UI Shell API to conditionally display, hide, and navigate content exposed in bounded task flows. Each new task flow dynamically opens in a tab panel. An inner toolbar can be used to manage opened tabs—to, for example, close all tabs or all but the selected tab, as implemented in the sample application.
The footer area consists of three facets you can use for adding copyright, status, and descriptive information.Adding the Dynamic Tabs UI Shell Template to a Page
To create a new JSF page based on the Dynamic Tabs UI Shell template, open and select a ViewController project and then choose File -> New. In the New Gallery dialog box, create a new JSF page, using the Page entry of the Web Tier -> JSF/Facelets option. In the Create JSF Page dialog box, select the ADF Page Template option, choose Oracle Dynamic Tabs Shell, and then click OK.
The new page opens in the visual page editor, showing the template facets and default labels. You can use the Oracle JDeveloper Structure window, shown in Figure 4, to add components to the template facets easily by dragging them there. To edit the template logo and default labels and messages, select the af:pageTemplate node in the Structure window and open the Oracle Property Inspector (Ctrl + Shift + I).
Figure 4: Visual editor, Structure window, and Property Inspector view of the sample application’s Index.jsf page
When you use the Dynamic Tabs UI Shell template, Oracle JDeveloper automatically updates the project libraries’ dependencies with a reference to the Oracle page template library. To see this, open the ViewController project properties by double-clicking the Projects node. In the Project Properties dialog box, select the Libraries and Classpath node and scroll through the list of configured libraries to locate the Oracle Page Templates entry. Select Oracle Page Templates, and click the View button to see the reference to the oracle-page-templates.jar file, which is an Oracle ADF library. This library contains—along with the page template itself—the Java classes and task flow configuration that provide the dynamic functionality. Click Cancel to close the dialog box.Dynamic Tabs UI Shell Template Architecture
By taking a deeper look at the Dynamic Tabs UI Shell template architecture, you’ll better understand how the template works and how it should be used and also learn some good Oracle ADF programming practices.
The Dynamic Tabs UI Shell template architecture consists of a JSPX document, a JSF page fragment, Java objects, Oracle ADF bindings, and task flow configuration files, as illustrated in Figure 5.
Figure 5: Dynamic Tabs UI Shell template architecture
The dynamicTabShell.jspx document is an Oracle ADF Faces page template—located in the Dynamic UI Tab Shell library Java archive (JAR) file—that defines the layout and facets. The Dynamic Tabs UI Shell template does not yet expose extension hooks enabling application developers to decorate the template’s default or customize the look. If you do require changes to the template, you can download and edit the template’s source code, available on Oracle Technology Network, and make it the basis of a custom template you then maintain.
In Oracle ADF, page templates can have an associated Oracle ADF binding file in which the template can expose Oracle ADF bound data content to the pages referencing it. The Dynamic Tabs UI Shell template uses the dynamicTabShellDefinition.xml Oracle ADF binding file, located in the tab shell library JAR file, to configure task flow bindings as placeholders for as many as 15 concurrent task flows that a template consumer page can reference and open in the local content area. Any attempt to open more than 15 task flows will cause an exception that the template will handle by displaying a preconfigured dialog box telling the user to close currently open tabs before new tabs can be opened in the local area.
Note that both the dynamictabShell.jspx and dynamicTabShellDefinition.xml files are internal and not accessible for modification.
An Oracle ADF DataBindings.cpx registry file is also deployed with the template to map the template JSF document (JSPX) with its Oracle ADF binding file, which is usually referred to as the PageDef file in Oracle ADF.
The TabContext.java class defines the public API of the Dynamic Tabs UI Shell template. Application developers—and the template, internally—use the public API to control the template behavior. Functionality exposed by the TabContext API includes
Add tab. Calling this API opens the referenced bounded task flow in a new dynamic tab within the local content area of the template. This option is best suited for isolated task flows.
Add or select a tab. Before opening a task flow in a new tab, the system checks whether this task flow already exists on a tab. If it does, the existing tab status will be changed to selected and displayed. This option is best suited for bounded task flows that share their Oracle ADF data-control instance with the parent page.
Access template UI components. The TabContext API exposes methods for accessing components that are privately used by the template, such as the inner tool bar, the global navigation tab container, the template content area, and the dialog box used to show system messages.
Access the tab transaction state. Tabs can be marked as having their content changed, in which case they are referred to as dirty. A warning dialog box will appear if users or the application try to close these tabs. A tab’s dirty state can be checked and manipulated with the TabContext API.
Because EL in Oracle JDeveloper 11g does not allow you to pass method arguments, you might need to use Java code exposed from a custom managed bean to access TabContext, using TabContext.getCurrentInstance();.
Whether necessary or not, it is a good practice to access the TabContext class from a custom managed bean, because doing so builds an abstraction layer between the application and the Dynamic Tabs UI Shell template behavior. Avoiding direct access to the TabContext objects enables you to define more-specialized APIs that make application EL references independent from future changes in the template’s public API.
The managed bean configuration of the TabContext class is referenced in the tabContext input parameter definition added to the 15 task flow bindings that the dynamicTabShellDefinition.xml file holds as placeholders for the task flows the template launches dynamically at runtime. For task flows used in the context of the Dynamic Tabs UI Shell template to reference the TabContext class, each task flow must expose a tabContext input parameter. The Dynamic Tabs UI Shell template uses the tabContext input parameter to inject a reference to its TabContext managed bean instance into each opened task flow. Using the injected reference, any called task flow can control the template behavior—to close or open tabs, for example.
As an Oracle ADF developer, you should adopt this context injection approach as a solution for your own interregion communication requirements. The CustomerOrdersCRUD-btf task flow in the BoundedTaskFlows.jws workspace accompanying this sample, for example, uses the tabContext reference to close the tab displaying the task flow upon rollback and commit—which also is when the task flow is exited. In addition, when data changes are performed within a task flow, the tab’s dirty state is changed to indicate to the template that the tab title needs to be shown in italics.
The Tab class in the Dynamic Tabs UI Shell template architecture is not considered a public API. Rather, it is used by and exposed through the TabContext class. The Tab class represents an instance of a tab in the local content area.
The blank.xml configuration file in the Dynamic Tabs UI Shell template architecture shown in Figure 5 defines an empty page that is always displayed when no tab is open within the local template content.Conclusion
The Dynamic Tabs UI Shell template provided in Oracle JDeveloper 11g enables developers to write rich internet applications with consistent page layouts and predictable behavior. In addition, the template promotes an application design based on Oracle ADF bounded task flows that unleashes the real power of Oracle ADF application development, setting the stage for code reuse, team development, modular application development, and increased developer productivity.
Photography by Unsplash