Not Yet Documented ADF Sample Applications

Send me a mail
 Dive into Oracle ADF   Click to see the XML version of this web page.   (Updated: 6/16/2008; 2:03:28 PM.)
Tips and tricks from Steve Muench on Oracle ADF Framework and JDeveloper IDE

Not Yet Documented ADF Sample Applications

As part of helping customers be successful with JDeveloper and ADF I'm often creating little example applications to illustrate a point. My goal is to document them and put them together with an OTN "HowTo" paper to accompany them, but I don't always have the time to do this. If you try to use one examples in the meantime and can't figure something out about how to use it, please post a question in the OTN JDeveloper discussion forum then drop me an email containing the link to that forum posting and I'll do my best to help.

Additional samples are available on the following ADF-related web sites:


Unless otherwise noted, the examples use the EMP and DEPT tables in the familiar SCOTT schema. If you would like SQL scripts to (re)create and populate the tables in the SCOTT and HR schemas, you can download demoscripts.zip.

NOTE for 10.1.3.x Examples: If the example you want to try was built with a JDeveloper 10.1.3.x release different than the one you are using, the only change you need to make to the downloaded workspace is to copy the correct versions of the adf-faces-impl.jar and jsf-impl.jar from the version of JDeveloper 10.1.3.x you are using to the example workspace's ./ViewController/public_html/WEB-INF/lib directory before opening/running the example in your version of 10.1.3.x. These files are located in the JDEVHOME/jlib and JDEVHOME/jsf-ri directories respectively

128.Synchronizing Emp Details with a Dept/Emp Tree [10.1.3.3] 21-FEB-2008

The Example.jspx page in this workspace illustrates a tree based on the Departments view object instance. The DeptView view object definition on which this view instance is based, is viewlinked to the EmpView view object with a view link accessor named EmployeesInDepartment. The tree binding in the page definition is configured with two rules in order to show the Dname attribute for the DeptView rows, to "drill down" into the EmpView details for each DeptView row using the EmployeesInDepartment view link accessor attribute, and to display the Ename attribute for each EmpView in the tree. The tree control has an id of myTree so that the panelGroup component surrounding the employee detail information can have its partialTriggers property set to that id. This way, any user interaction with the tree control will repaint the panelGroup and everything inside it. Since we want to be able to conditionally toggle the rendered property of the panelBox on and off, combined with the fact that you cannot trigger a partial page refresh event for a UI component that is not rendered, we need to introduce this wrapping panelGroup component to be a stable UI component in the page on which to configure the partial page updating. The nodeStamp facet of the tree component includes an switcher component to conditionally render the tree nodes based on the current level of the tree. The current level of the tree is determined by referencing the expression node.hierType.viewDefName which allows us to access the fully-qualified view definition name of the hierarchy type (representing the tree binding rule) of the current node. This will return a string of "test.model.DeptView" for the nodes in the tree coming from the DeptView view object, and a string of "test.model.EmpView" for the nodes coming from the EmpView view object. In order to avoid using these "raw" view definition names as the switcher component's facet names, we introduce a treeLevel map in the Example backing bean to map the view definition name to a logical facet name. The entries in this map {(""test.model.DeptView", "DeptNode"), ("test.model.EmpView", "EmpNode")} are configured declaratively in the faces-config.xml file using the JSF managed bean facility. The facetName property of the switcher is set to the EL expression "#{Example.treeLevel[node.hierType.viewDefName]}" which resolves to the logical facet name corresponding to the view definition name of the current node in the tree, via this map. In other words, DeptView nodes render using the contents of the DeptNode switcher facet as a outputText, while EmpView nodes render using the contents of the EmpNode facet as a commandLink. The command link is configured to have its action listener invoke the declarative action binding setCurrentRowInEmployeesIteratorWithKey which is the name of the action binding in the page definition that uses the built-in setCurrentRowWithKey operation against the EmployeesIterator iterator binding. This action binding is configured to pass the value of the EL expression "#{node.rowKeyStr}" as the one parameter this built-in operation requires. It is the stringified row key of the current node in the tree that the user has clicked on. In the Example backing bean, the onTreeNodeDisclosed method is configured as the tree's disclosureListener. It has a bit of code to set the set of expanded tree nodes to be only the currently selected node, as well as a line of code that hides the employee information panel box by setting its rendered property to false. The onClickEmployeeCommandLink is configured as the action of the commandLink in the tree and it includes one line of code that shows the employee info panel box. This panelbox includes a panelForm that shows the employee detail information and allows the user to edit the salary. In order to avoid the tree interaction from posting data, it has its immediate property set to true. This way, any user change to the form is saved only if the user explicitly clicks on the (Save) button. Last, but not least, the commandLink includes a nested resetActionListener component to ensure that the editable UI components on the page "pull" or "reset" their bound values after the partial page request caused by clicking on the tree. This ensures that the Sal field on the employee detail panel is always correctly showing the value of the current employees salary.


 

127.Counting Number of Rows Changed (Inserted, Updated, Deleted) [10.1.3.3] 20-FEB-2008

This example illustrates an approach to count the number of rows changed in the transaction (presumably for notifying the end user). In the example, the total number of changed rows (also broken down by inserts, deletes, and updates) is printed to the console. The implementation involves a customized DBTransactionImpl class which manages the counters in the UserData hashmap in the Session and a custom EntityImpl class (used by the Emp EO in the project) which increments the appropriate insert, update, or delete counter in its afterCommit() method.


 

126.Using Comma-Separated String Bind for Variable IN List [10.1.3.3] 10-JAN-2008

This example illustrates a simpler way to achive a variable IN list in a view object's query. For example, imagine that you want a DeptView view object to feature a WHERE like DEPTNO IN (:TheDeptNo) but you need the IN clause list to allow specifying one or more department numbers at runtime. One approach illustrated by example number 1 below involves writing some code that assigns an array of one or more deptno values for the bind variable. The approach presented here avoids the need for any code in the ADF layer by using a database function instead. Run the CreateTypeAndFunction.sql script to create the NUM_TABLE type and the IN_NUMBER_LIST() function. The function accepts a comma-separate string argument and returns a NUM_TABLE as its result. This allows the CommaSeparatedListOfDeptno bind variable in the example's DeptView view object to be of type String. The view object's WHERE clause looks like DEPTNO IN (SELECT * FROM TABLE( CAST ( in_number_list(:CommaSeparatedListOfDeptno) as num_table) ) ). Run the AppModule in the tester can try entering values like "10" and "10,40" for the bind variable to see it in action.


 

125.Uploading Contents of af:inputFile to a CLOB Column [10.1.3.3] 03-OCT-2007

This sample is a CLOB-based version of example #85. Using ADF BC's support for the Oracle Intermedia ORDImage, ORDDoc, ORDAudio, and ORDVideo, you can simplify uploading, downloading, and displaying media and documents. However, since numerous users have asked for it, this example illustrates a simple JSF page with an inputFile component and the backing bean logic to handle inserting the contents of the uploaded file into a CLOB column in the database. Run the CreateTables.sql script to drop and create the simple UPLOADED_FILES table. Then, run the UploadFileToClob.jspx page. Note that the page uses the af:form container with its usesUpload attribute set to true. Also notice that the inputFile control is bound to the backing bean property named fileInputComponent, allowing the backing bean to reference the UI component programmatically. The valueChangeListener on the inputFile is mapped via EL to the onFileUploaded() method in the backing bean. That method accesses the ExampleModule client interface of the ExampleModule application module, and invokes the saveUploadedFile() method on it. It passes in the file name, and a ClobDomain class representing the contents of the uploaded file. The (Upload File) button's action property is mapped via EL to the onUploadFileButtonClicked() method in the backing bean. This method either displays an error message if the filename to be uploaded is bad, or else causes the "Last File Files Uploaded" iterator to be re-executed to retrieve the latest list of the last file files uploaded (by any user). See Configuring ADF Faces File Uploading Servlet Parameters for information on some settings you might need to configure.
 

124.Validating and Rendering Conditionally Required Attributes [10.1.3.3] 10-SEP-07

This example illustrates how to validate and render conditionally-required attributes. After running the included CreateTables.sql script to create the OPTIONAL_REQUIRED_TEST table, run the TestPage.jspx to see that when a row has its RowType attribute set to the value A then the ValueA inputText component renders, while if its RowType attribute is instead set to the value B then the ValueB inputText field renders. These fields set the showRequired property to true to show the required field indicator to the end-user even though the underlying ValueA and ValueB attribute are not marked as mandatory. The conditional mandatory validation is performed in the TestEntity entity object using entity-level method validators. The radio group UI component is marked to have its autoSubmit property true, and the ValueChangeListener method in the backing bean for the page sets a request-scope attribute as a flag to indicate that the row type is changing. This flag is then referenced by the ConditionalValidationPageController -- identical in function to the one you might have seen in Example# 62 Cascading Lists in JSF -- which is configured to be used by the TestPage by setting the ControllerClass property of its page definition. This customized page controller avoids validating the row if it detects that the row type is changing. The conditional rendering of the ValueA or ValueB inputText components is handled declaratively using an appropriate EL expression for the component's rendered property. When the autoSubmit radio group (with component id "RowTypeRadio") causes its partial-page request, the panelForm component in which the ValueA and ValueB inputText's reside is declaratively "repainted" by having its partialTriggers attribute set to that "RowTypeRadio" id value. By performing the partial-page triggering on the enclosing panelForm component, you avoid the gotchas related to having PPR events delivered to currently-unrendered components.
 

123.Using a Custom Number Formatter to Parse/Format Social Security Numbers (SSN) [10.1.3.3] 31-AUG-07

This example includes a SocialSecurityNumberFormatter class that extends the default ADF Business Components number formatter class (DefaultNumberFormatter). It overrides the parse() and format() methods to implement the parsing and formatting of a United States social security number whose format is 000-00-0000. The default number formatter does not work with this format mask as is because the JDK DecimalFormat class on which it's based doesn't correctly support that format mask as you might expect. You'll need to run the provided CreateEmpWithSocialSecurityNumber.sql script to create a version of the EMP table with an addition SSN column to store the social security number as a numerical value. The Emp entity object sets the custom property named Ssn_FMT_FORMATTER to the fully-qualified class name of the custom formatter class. This property and its value are stored in the entity object's companion EmpImplMsgBundle.java message bundle class. The CustomDCErrorHandler class in the FwkExtensions project contains logic that sets the attribute information on the DataCreationException that is thrown if that information is not already provided in the exception. This allows the error message to be correctly reported as an exception specific to a given attribute. Run the TestPage.jspx page to try entering valid and invalid social security numbers. Notice that the default <f:convertNumber> component has been commented out for the <af:inputText> component for Ssn on the page.


 

122.Running Custom Backing Bean Code Before/After Default Table Selection Listener [10.1.3.2] 16-AUG-07

This example illustrates a TestPage.jspx page with an af:table component whose selectionListener property has been modified from the default EL expression dropped when the table was created, to instead call a selection listener method named onTableSelectionChanged() in the TestPage backing bean. This default EL expression normally looks like #{bindings.TableBindingName.collectionModel.makeCurrent} which declaratively "wires" the table selection event to invoke the makeCurrent() method on the CollectionModel of the table binding. In order to preseve the default data binding functionality that reacts to the table selection change, this backing bean method uses the invokeMethod() helper method of the EL helper class to call the default functionality with custom code before and after it. The EL helper class is in the FwkExtensions project, which is marked as a project-level dependency.
 

121.Declaratively and Programmatically Refreshing a View Object's Query Results [10.1.3.2] 24-JUL-07, Upd: 27-JUL-07

This example contains four JSF pages that each show a table of department rows. The Departments.jspx page illustrates how to use an invokeAction combined with an Execute operation binding (and appropriate settings for the Refresh and RefreshCondition properties of the invokeAction) to conditionally refresh a view object's query results based on the presence of a request-scope flag attribute. You can read more about these settings in section 10.5.5 How to Use Refresh Correctly for InvokeAction and Iterator Bindings. The AnotherPage.jspx, to which you can navigate from Departments.jspx, contains two af:commandLink components that navigate back to the Departments.jspx page. One of those links uses a nested, af:setActionListener component to declaratively set the value of the request-scope attribute named refreshFlag to the value true. The presence of this flag attribute causes the invokeAction mentioned above to force a requery of the rows. The DeptView view object is instrumented to print a diagnostic message to let you see when its base query and its estimated row count query get executed. The range size of the iterator binding used on this page is set to 2 to you can see the table paging behavior even with only 4 rows of DEPT table data. When you use an af:table and have a range size of N set on your iterator binding to show only N rows per page, then the estimated row count query will be used since the table component needs that count to build its paging control. The DepartmentsProgrammatic.jspx page is nearly identical to the Departments.jspx page, except that it illustrates how to accomplish the conditional requery of the view object from code using the basic technique described in section 10.5.4.3 Using Custom ADF Page Lifecycle to Invoke an onPageLoad Backing Bean Method section of the ADF Developer's Guide for Forms/4GL Developers. It also uses a range size of 2. The DepartmentsAlwaysRequestOnPageEntry.jspx page illustrates how to create a page the refreshes its data each time you navigate to it from another page (but not when you post-back to it from the same page). And finally, the DepartmentsTimedAutoRefresh.jspx page illustrates how to use the combination of an af:poll component and an Execute action binding to refresh the page without user intervention every 5000 milliseconds (i.e. 5 seconds). Notice that the af:poll component has an id attribute set to the value "timer" and that an af:outputText on the page as well as the af:table UI components list this "timer" id in their partialTriggers property so that they will be partial-page refreshed to "repaint" any updated results. The af:outputText just shows the current date/time to make it easier to see when the timer is firing. In constrast to the other three pages, this page has no explicit (Refresh) button, so to create the Execute action binding in the page definition I selected the Go to Page Definition choice in right mouse context menu of the JSPX page visual editor window and then used the Structure Window view of the page definition for that page to select the bindings heading and {Insert Inside bindings -> action} right-mouse menu choice to create an action binding for the DepartmentsIterator using the built-in operation named Execute.
 

120.Simple AJAX-Style Partial Page Rendering (PPR) Example with AutoSubmit SelectOneChoice Control [10.1.3.2] 14-JUL-07

This examples contains a single JSF page with an EmpView editing form. The EmpView view object includes the Emp entity object as its primary entity usage, as well as the Dept entity object as a secondary, reference entity usage, in order to display the related Loc value for the department to which the current employee is assigned. The Deptno is bound to a af:selectOneChoice component whose autoSubmit property has been set to true. This causes a PPR postback whenever the end-user changes the value of the list. The Loc field is displayed as a read-only af:inputText, and has its partialTriggers property set to the value of the id of the af:selectOneChoice component ("DeptnoPoplist") that should trigger the partial page re-paint of the that Locaf:inputText component. When you run the page notice that if you navigate between rows in the EmpView the PPR counter at the top of the page increments to illustrate that the entire JSF page is being re-rendered. In contrast, if you just change the value of the autoSubmit-enabled Deptno poplist, then the value of the corresponding Loc field repaints on the page, but the PPR counter at the top stays the same (since only the bit of the page that needed to be repainted was redrawn). Notice that other than the PPRDemo managed bean that facilities showing a counter on the page to better visualize when PPR is occurring and not, the example requires no Java code to implement.
 

119.Simple EJB-Based CRUD-Style Contacts Application [10.1.3.2] 13-JUL-07, Upd: 23-JUL-07

This example illustrates a simple JSF application that allows you to list, edit, add, and remove contacts. The MyServiceBean in the Model project is the stateless EJB 3.0 Session Bean that acts as the business service. To keep the example simple, the session bean works with an in-memory set of Contact POJOs (Plain Old Java Objects). The Session Bean's service methods each prints a diagnostic message to the console so you can better understand and appreciate when the ADF Model layer is working with the cached results of the finder methods as well as when it invokes business service facade methods to add, edit, and remove a Contact. The example is designed so that when the name of a Contact is changed, the Contact's updated property is updated inside the business service to reflect the update time. When a new contact is added, edited, or deleted, the application causes the executeQuery() method on the method iterator to be executed to rebuild the RowSet of data being managed by the RowSetIterator of the iterator binding.

When an iterator is refreshed during the ADF page lifecycle it gets a chance to decide whether its data needs to be recalculated by asking the business service, or whether it can use its cached data. For a method iterator, this decision is based on checking whether the associated method action has stored the result of its execution yet for a given set of its parameter values. If either its result has not yet been calculated, or if any of its parameter values has changed, then the method iterator is implicitly requeried. When a method iterator is requeried, it invokes its related method action binding and caches the result (unless the CacheResults property is explicitly set to false, which is not the case in this example!) and then rebuilds the RowSet of Row objects that wrap the actual data beans -- Contact beans in this example. These Row objects adapt all bean data to have the same generic API and delegate to the wrapped "dataProvider" bean in each row to get/set the attribute values. It illustrates both programmatic and declarative techniques for accomplishing this: the former by invoking the executeQuery() in backing bean code, while the latter using a combination of an Execute action binding related to the method iterator and an invokeAction executable whose Refresh and RefreshCondition properties have been set to control the ADF lifecycle phase during which the Execute action should fire as well as a boolean EL expression to qualify under what conditions it should fire. You can read more about these settings in section 10.5.5 How to Use Refresh Correctly for InvokeAction and Iterator Bindings. It's important to note that since the findContactsByName(String) method takes a parameter, we take maximum benefit of the ADF Model layer's results caching when we insure that the EL expression used to pass the method action parameter continues to evaluate to the same value used when the data was originally retrieved. In this example, the value of the nameSearch that the end-user might apply to filter the results is kept in the session-scoped UserInfo managed bean so it can be referenced by the method action on both the ListPage.jspx and the EditPage.jspx pages. If you are not careful to insure this, then having the parameter values be different on different pages, given the conditions described above for the implicit execution of the method iterator, will cause potentially unwanted re-execution of the business service methods. The FwkExtensions project in the example includes generic helper objects and framework extension classes to customize the error handling very similar to those described in the ADF Developer's Guides. The FindOrMergePage.jspx illustrates an example of performing data binding to a method result that returns a single Contact bean instead of a collection of beans (List<Contact>), using the helper method executeQueryForMethodIterator to re-execute the method iterator's query (since JDeveloper design time prevents the creation of a declarative Execute binding against such a method iterator at the moment). If you enter an email address on this page, it will find an existing contact by email if it exists and update its name if you supply a non-null value for the name parameter. If you enter an email that does not exist, it will add it to the list. This page also shows off some programmatic techniques for conditionally clearing the page definition variables used by the ADF parameter form dropped onto the page. Since the FindOrMergePage can make updates as well as add new rows, the af:commandLink on the page sets the requestScope flag to signal to the ListPage to refresh its data on navigating there.
 

118.Selectively Uppercase String Bind Variable Values Through a Custom Metadata Property [10.1.3.2] 11-JUL-07

This example illustrates a framework extension class CustomViewObjectImpl that overrides the bindParametersForCollection method to conditionally uppercase any String-valued bind variable parameter values that happen to have a custom metadata property named Uppercase set on them in their bind variable definition. You can use the view object editor to inspect the bind variable named TheName on both the DeptView and EmpView view objects to see that they both have this Uppercase custom metadata property set. Both of these view object specify CustomViewObjectImpl as their base class in inherit this new, generic functionality that is metadata-driven. To experiment with the example, run the application module and enter a department name is lower/mixed case like "research". Then click on the ":id" icon of the detail Employees view instance and try filtering the employees to ones whose Ename starts with the letter "s" (entered in lowercase, too).
 

117.Editable Checkbox in an ADF Faces Table [10.1.3.2] 19-JUN-07

This example illustrates a simple technique for supporting an editable checkbox in an ADF Faces table to allow toggling a persistent status flag on or off. Before running the example JSPX page, run the CreateTable.sql script in the Model project to create a SETTINGS table with three rows of example data. Since SQL does not have a native boolean datatype to use for the type of a column in a table, the STATUS column in the SETTINGS table is defined as NUMBER(1) with 0 representing false and 1 representing true. The example illustrates how you can introduce a transient Boolean-valued attribute StatusAsBoolean to work with the numerical true/false value as a Boolean. In the custom SettingsViewRowImpl row class, the getStatusAsBoolean and setStatusAsBoolean methods have been written to convert the numerical value to a boolean upon reading it and convert a boolean value to the correct Number value upon writing it. In the JSPX page in the ViewController project, the af:selectBooleanCheckbox is bound declaratively to the StatusAsBoolean attribute in the current row using the EL expression #{row.StatusAsBoolean}. When you run the page, try changing the state of the checkboxes and clicking (Commit). Then from SQL*Plus, you can verify that the changed boolean checkbox states have been correctly saved as 0 or 1 appropriately.
 

116.Including Multiple Levels of Automatically-Updated Reference Information in a View Object [10.1.3.2, HR schema] 09-MAY-07

This example illustrates an EmployeesView view object that queries employees from the HR schema. It contains four levels of reference entity usages, showing for the current employee: (1) the name of the Department they work in, (2) the StreetAddress of the Location of that Department , (3) the Country name in which that location resides, and (4) the Region name in which that country resides. Run the DemoModule in the ADF Business Components browser and double-click on the Employees view object instance to see its data. Experiment with changing the DepartmentId foreign key attribute of an existing employee to notice that all four levels of reference information correctly synchronize. You can use the AllDepartments view object instance to remind yourself of what some valid department id numbers are, and you can use the four-level master/detail-coordinated view object instances (Regions -> Countries -> Locations -> Departments) to understand better what to expect when changing the DepartmentId. The trick to having this multi-level reference information synchronization work correctly is that at each level the foreign key attribute referencing the next level is included in the view object's attribute list. Notice that the attributes whose names start with "PK" in the view object have a Display control hint set to "Hide", so the ADF Business Components browser hides them.
 

115.Custom Domain to Persist Transient ArrayList of Account Beans [10.1.3.2] 03-APR-07

This example shows a custom ListOfAccounts domain that implements the necessary interfaces to allow its contents -- a list of Account beans -- to be passivated and activated correctly to the application module persistent state snapshot. It shows a combination of required aspects including implementing the XMLDomainWriter and DomainInterface interfaces, as well as containing a public static getXMLDomainFactory() method that returns an instance of a class that implements the XMLDomainReaderFactory and XMLDomainFactory interfaces. The ExampleTransientView in the project is a transient view object with one String-valued attribute marked as the key attribute, and another ListOfAccounts attribute of type model.types.common.ListOfAccounts, our custom domain. Both of these attributes are marked as updateable and have their "passivate" property set to true. This view object's create() method contains the best practice code required for a transient view object that will be programmatically populated by creating and inserting rows. Run the TestClient class to exercise the creation of two rows in the transient view, passivating the transient state, releasing the application module, acquiring a new application module, activating the passivated state, and iterating the transient rows again.


 

114.Showing a JSF Message if Search Produces No Rows or Too Many Rows [10.1.3.2] 30-APR-07

This example illustrates a SearchPage.jspx built using the technique described in section 18.3.5 How To Create Search and Results on the Same Page of the ADF Developer's Guide for Forms/4GL Developers that has been enhanced with a small amount of backing bean code that customizes the ADF page lifecycle to add a JSF FacesMessage in case the EmployeesResultsIterator returns either no rows or too many rows (with the limit hard-coded for this example to 10). The SearchPage backing bean inherits from the BackingBeanBase class as described in section 10.5.4.3 Using Custom ADF Page Lifecycle to Invoke an onPageLoad Backing Bean Method of the Dev Guide (simplified slightly by using my favorite EL helper class). The rendered attribute on the af:table showing the search results in the SearchPage.jspx uses an EL expression to cause the table to render only when the number of rows found is between 1 and the maximum allowed (10).


 

113.Apply Bind Varible Values to Filter View Link Accessor RowSets [10.1.3.2] 17-APR-07

This example illustrates a TestPage.jspx with a tree binding based on a Departments view object instance of type DeptView. The WorksInDeptLink view link defines a view link accessor attribute named EmpView that is used by the tree binding to access the detail rowsets of employees for each department. The DeptView view object defines a custom method named setLowHighSalaryRangeForDetailEmployeesAccessorViewObject() that is exposed on the view object's client interface. The TestPage.jspx includes a declaratively-bound parameter form for invoking this method, passing in values for a low-salary and high-salary range. This method accesses the view object instance that the system creates at runtime to support the view link accessor accesses, and sets the values of the two named bind variables defined by the EmpView. The DeptViewImpl class also contains an overridden createViewLinkAccessorRS() method that applies the bind variable values to each view link accessor rowset created. Run the TestPage.jspx page and enter values for the low and high salary range you want to see for employees in the tree. For more information on the difference between the view object instances in the application module's data model and the system-created view object instance used to provide the view link accessor attribute rowset, see 27.1.3 Understanding View Link Accessors Versus Data Model View Link Instances.
 

112.Using XSQL Pages with ADF Iterators in a JSF Application [10.1.3.2] 22-MAR-07

This example illustrates a TestPage.jspx with a button whose action navigates to an XSQL page TestPage.xsql to format the data in the iterator using XML/XSLT techniques. The TestPage.xsql uses the custom XSQL action class test.view.xsql.ADFViewObject that is identical to the one that appeared in the ADF Toy Store Demo, only refactored to live in a different package. The interesting things to note about getting this example to work are: (1) The web.xml file defines a filter-mapping for the *.xsql URL pattern, (2) the DataBindings.cpx has been modified in the code editor to contain an additional page mapping entry for the /TestPage.xsql path so ADF knows what page definition you want to use for that page, and (3) by insuring that the URL requesting the page contains the "/faces/" prefix in the path, this triggers the handling of the request by the Faces Servlet (and indirectly the ADFPhaseListener that is registered to be used by the Faces infrastructure). This makes sure that the request-scoped bindings attribute is correctly set to reference the current page's runtime binding container.
 

111.Avoiding Runtime Describe Overhead When Defining Dynamic Read-only View Objects [10.1.3.2] 19-MAR-07

This example illustrates the code necessary to programmatically create view definitions at runtime for dynamically-created SQL-based view objects to avoid the runtime DESCRIBE overhead that is associated with using the simpler API createViewObjectFromQueryStmt(). The TestClient program calls an application module's client interface method named createViewObjectAndViewLinks(). That method constructs two view objects instances and a view link between them. Then, the client code finds and iterates through the results of these view objects. Since we programmatically define the names and data types of the view object's attributes, ADF will not need to perform a runtime DESCRIBE (involving a round-trip to the database) to discover that information at runtime.
 

110.Updating Another Area of the Page When Table Selection Changes [10.1.3.2] 15-MAR-07

It's common to want a JSF page with a summary table that allows the user to select a current row and a detail area showing more information about the currently selected row. If you have enabled the autoSubmit property of the af:tableSelectOne component your af:table's selection facet, then it can be a little puzzling why the other information on the page does not update when you change the current row. This example illustrates how to declaratively configure your af:table and an af:panelForm that displays additional information about the selected row in the table. The secret lies in configuring the partialTriggers property of the component that you want to be updated when the table selection changes. In the example, you see that I'd assigned an id of myTable to the af:table component, and on the af:panelForm component I've listed myTable as one of the component id's that should trigger a partial-page request "repaint" (of the af:panelForm). To allow you to experiment with toggling the autoSubmit property of the tableSelectOne on or off at runtime, I've configured a simple SessionSettings session-scoped managed bean that has a single property named useAutoSubmit. By setting the value property of the af:selectBooleanCheckbox at the top of the page to the EL expression #{SessionSettings.useAutoSubmit} we can allow the user to use the checkbox to toggle the value of that managed bean property. By also using the same EL expression #{SessionSettings.useAutoSubmit} for the value of the af:tableSelectOne component's autoSubmit property, we allow the changing value of the managed bean property to influence the runtime behvaior of the table selection to be auto-submitting or not. Finally, since a change in state of the checkbox needs to cause the table to repaint, I have assigned an id value of tableAutoSubmitControl to the checkbox, and listed that tableAutoSubmitControl component id in the partialTriggers property of the af:table. At runtime, you'll see that if auto-submit it off, then the current row changes when you click on the (testCurrentRow) button. If auto-submit is on, then the current row changes as soon as you click into the radio group button on the new current row. In both cases, the panelForm to the right is updated to reflect the values of the new current row. The (testCurrentRow) button is a bound declaratively to the testCurrentRow() method on the application module's client interface. It was created by dropping that method from the Data Control Palette onto the page. When you click on the button, you can see that the getDeptView1().getCurrentRow() method call inside that method already "sees" the new current row (and prints out its Deptno value to the console).


 

109.Declaratively Populating Attributes from an Oracle Sequence [10.1.3.2] 15-MAR-07

Section 9.4.1.2 Eagerly Defaulting an Attribute Value from a Database Sequence from the ADF Developer's Guide explains the two lines of code you would add to an overridden create() method of your entity object to programmatically populate its primary key attribute from a sequence at row-creation time. Even though this is only a couple of lines, if many of your entity objects have sequence-valued primary key attributes and you are not using database-trigger-assigned sequence values (described in section 6.6.3.8 Trigger-Assigned Primary Key Values from a Database Sequence), then you might be interested in a more generic, metadata-driven solution. This example illustrates a simple CustomEntityImpl framework extension class on which both the Dept and Emp entities in the sample are based. It's overridden create() method tests for the presence of a custom attribute-level metadata property named SequenceName and if detected, populates the attribute's default value from the next number in that sequence using the same basic code as above. The Dept entity defines the custom SequenceName property on its Deptno attribute with the value DEPT_TABLE_SEQ, while the Emp entity defines that custom property on its Empno attribute with the value EMP_TABLE_SEQ. The supplied CreateDeptAndEmpTables.sql script creates the tables and sequences for you.
 

108.Customzing ADF Faces Convert Number Detail Error Message from a Message Bundle [10.1.3.2] 05-MAR-07

The af:convertNumber tag supports a number of attributes that allow you to customize the detail error message when conversion fails. For the basic number conversion failure, this attribute is named convertNumberMessageDetail. In order to reference a resource bundle message, normally you would expect to be able to use an f:loadBundle tag in your page to define a variable for a Map of the resource bundle strings, and then reference the message using an EL expression like #{res.NOT_A_NUMBER}. The complication is that the resource bundles loaded with loadBundle are only available during the page rendering phase, but not during the validation phase. So, in order to drive the convertNumberMessageDetail from a message bundle, I needed to borrow some of the code from the JSF reference implementation's loadBundleTag class that exposes a resource bundle as a Map, and I put it in the AppliationMessageMap managed bean class in this example. I've configured that to be a session-scoped managed bean and configured its basename managed property to have the value view.resources.JSFMessages in faces-config.xml. This allows me to reference my custom error message for "Field 2" in the demo, in its f:convertNumber tag's convertNumberMessageDetail attribute using the EL expression AppMessages.messages.NOT_A_NUMBER. To see the custom error message, try typing a value like "adf" into Field 2 and clicking (Submit). You can run the demo with your browser set to prefer "Italian [it]" to see the custom error message translated in Italian.
 

107.Displaying ADF BC Mandatory Field Errors Using UI Hint Labels [10.1.3.2] 05-MAR-07, Upd: 13-MAR-07

The TestPage.jspx page in this example contains an ADF Form dropped from the data control palette based on the Employees view object. It consciously chooses to avoid performing client-side required-field validation by not setting the required property of the inputText controls (which defaults to false). Instead, it sets the showRequired property of the components to the same EL expression that would normally be used by the client-side required property. This has the effect that required fields are rendered with the visual required indicator, but the mandatory field validation is performed by the ADF BC layer instead of on the client. The ViewController project includes a custom ADF Phase Listener, a custom Faces Page Lifecycle class, and a custom ADF Error Handler class just like the SRDemo sample application (explained in section 20.8.1 of the Dev Guide) in order to customize the error reporting behavior. A few enhancements that have been made in this example's version of these classes are (1) The use of the getComponentClientId method on the FacesCtrlAttrsBinding object to retrieve the Faces component client id in order to construct a FacesMessage that is specifically related to a given UI component, (2) the use of the ADF Faces LabeledFacesMessage class to create a FacesMessage that remembers the label of the component to which it's associated, and (3) the special-case handling of AttrSetValException errors for mandatory fields in order to display a custom string from the CustomMessageBundle using the end-user-friendly UI label string of the attribute name that is required. In addition, since we've disabled the use of client-side mandatory field enforcement, combined with the fact that the ADF model layer does not by default validate the binding container if the end-user has not entered any values into any of the fields, we've overridden the validateModelUpdates() method in the CustomFacesPageLifecycle class in order to call a helper method forceValidationOfNewRowWithAllNullMandatoryAttributes() which does what it's name suggests. This ensures that if the user creates a new row and immediately clicks (Save) without entering any values for any fields, they see the expected errors about any mandatory fields. In addition, by running the TestHomePage.jspx you can running two different standalone create forms by clicking on an appropriate command button. The CreateNewEmployeePage.jspx page is a more traditional, declarative create form based directly on a view object as described in section 13.6 Creating an Input Form of the Dev Guide. The CreateNewEmployeePageUsingAMMethodViaEntity.jspx page shows an alternative approach that requires coding an application module custom method, exposed on its client interface, dropped onto the page as an ADF Parameter Form. Note that using the method-based approach, the method parameters are named the same as the underlying entity object attributes so that the created page definition variables and bindings have names that match the entity object attributes. Also note that the application module method uses an entity-based view object to create the new employee rather than directly creating the entity object so that the automatic bundled-exception handling is preserved. Try setting the "Ename" to the value XXXXX in order to observe what happens when an attribute-level validation rule fails. Finally, also note that the UI Hints for the parameter form page definition variables are defined in a message bundle specific to the page definition. With the view object based approach, those are automatically inherited from the underlying entity object. The example also illustrates the use of selectOneChoice "dropdown list" controls for mandatory fields. Their corresponding list binding is configured to allow a null value to correctly handle the fact that in a newly-created row the value of that attribute will be null if your entity object does not provide an alternative default value. The example contains workaround code in the form of the viewcontroller.util.ListBindingHelper to workaround bug# 5930745 where an additional blank entry can inadvertently be added to the list when the list binding related to a selectOneChoice control has a validation exception due to its being mandatory. Finally, the backing beans for the CreateNewEmployeePage and the CreateNewEmployeePageUsingAMMethodViaEntity pages were created in order to workaround bug# 5930784 where ADF/JSF incorrectly performs page navigation even when exceptions have been registered on the current page. By double-clicking on the declaratively-bound button and allowing JDeveloper to generate the ADF binding code in the backing bean, this reliably avoids page navigation when the action binding has caused exceptions to be raised. If you notice that sometimes the attribute-level exceptions are reported with errors that appear next to the fields and other times with errors reported only at the top, this is related to bugs# 5918276 and 5929646 where the getComponentClientId() function of the FacesCtrlAttrsBinding returns null if the binding has not previously "seen" a non-null value during the session as well as the fact that the FacesCtrlListBinding does not support a getComponentClientId() method. It is the ability to retrieve the client id of the component related to a binding that allows this example's custom error reporting to construct an ADF Faces Message that will be rendered next to the component to which it relates.

You can run the demo with your browser set to prefer "Italian [it]" to see the page translated in Italian.
 

106.Further Filtering View Link Accessor RowSets at Runtime [10.1.3.1] 08-FEB-07

The test() method in the TestModule in this example illustrates the important point discussed in section 27.1.3 Understanding View Link Accessors Versus Data Model View Link Instances of the ADF Developer's Guide for Forms/4GL Developers. It highlights how the view link accessor rowset is based on a distinct, system-created view object instance as compared with the developer-created view linked detail view object instance in the data model, despite the fact that they are both instance based on the same base view object definitionEmpView. The code shows adding an additional runtime WHERE clause filter to the view link accessor rowset by accessing its view object instance, and then performs a similar task on the data model detail view object instance to show they are indepdent. Run the TestClient.java class to see the results of the test() method in action.


 

105.Efficiently Enforcing Uniqueness of Non-Primary Attribute Value [10.1.3.1]

This example illustrates how to implement an efficient existence check to enforce the uniqueness of a non-primary-key attribute. Using a Dept entity object based on the DEPT table, we assume that in addition to the Deptno primary key's uniqueness that is declaratively enforced using the ADF UniqueKeyValidator, we also want to enforce the uniqueness of the Dname attribute value. For the sake of argument, we assume we'd like the value to be unique in a case-insensitive way so that we won't allow one department called "Sales" while another is named "SALES". The DeptDefImpl class in this example implements an existsByDname() method following the technique outlined in section 9.6.2 Implementing an Efficient Existence Check of the ADF Developer's Guide for Forms/4GL Developers. This routine on the custom entity definition class uses the FindDeptByUniqueDname view object to test case-insensitively whether a row exists in the DEPT table with the supplied department name. If it doesn't exist in the database, it then searches the entity cache to detect whether perhaps another new instance created in the current transaction might already be using the candidate department name value, too. The Dept entity object class has an attribute-level method validator defined to trigger the validateDname() method in the DeptImpl class. This method gets the custom entity definition class and calls the existsByDname() method, returning true if the candidate department name does not already exist. See section 9.3.1 How to Create an Attribute-Level Method Validation for more information on creating an attribute-level method validator. You can use the ADF Business Components tester to verify that it's impossible to insert two departments with the same department name.


 

104.Selecting a Row to Edit from a Popup Dialog [10.1.3.1]

The EditDepartment.jspx page in the example allows the user to edit a row in the DEPT table. A button on that page has its Action property set to dialog:selectDepartment and has its useWindow property set to true so that it invokes a modal, popup dialog containing the page SelectDepartment.jspx. The commandButton on that page contains a nested af:returnActionListener component whose value is provided by the EL expression #{row.rowKeyStr}. That will evaluate to the string format of the current row's key (described in more detail in section 10.5.6 Understanding the Difference Between setCurrentRowWithKey and setCurrentRowWithKeyValue of the ADF Developer's Guide for Forms/4GL Developers.) The onReturnFromSelectDepartmentDialog return listener method in the EditDepartment backing bean shows how to process the selected key value returned from the dialog and to set that row as the current row for editing, followed by forcing the calling page to refresh.


 

103.Programmatically Scrolling the JSF Table's Current Page of Rows [10.1.3.1, HR schema]

The ProgrammaticScroll JSF backing bean in this example illustrates three different approaches to perform programmatic scrolling of the 25 rows in the HR schema's COUNTRIES table. Run the ProgrammaticScroll.jspx page and try using the (<<) and (>>) buttons, optionally changing the scrolling increment value in the text field located between these buttons. You can use the drop-down list to pick among the three different programmatic scrolling approaches.


 

102.Entity Object with Attributes that Must be Stored in Encoded Format [10.1.3.1]

This example illustrates the methods to override in order to implement an entity object one or more of whose string attributes must be stored to the database in an encoded format. The example includes a simple CreateTablesAndPopulateData.sql script that creates a USER_INFO table with USERNAME and PASSWORD columns. As a trivial example of a entity object String-valued attribute stored in encoded format, the corresponding UserInfo entity object assumes that its Password should be stored in this way. The encoding technique employeed in the example is simple. A string like "abcd" is encoded when stored in the database as "[dcba]", that is, with its letters reversed and surrounded by brackets. Upon retrieving the entity object data from the database, the example decodes a queried value for the password by turning a string like "[dcba]" back into "abcd". The code is implemented as a CustomEntityImpl framework extension class, which the UserInfo entity uses as its base class. The generic encode/decode logic in this class is enabled on an entity object's String-valued attribute by setting the custom attribute property named EncodeValue, which the UserInfo entity's Password attribute has set. I was hoping the code involved would have been more elegant, and if I discover a more elegant approach I'll update this sample to reflect what I learn. Of course, we make the assumption that encoded attributes are not going to be user-queriable, however the example code does nothing to stop the user from trying to query on it.


 

101.Reporting Model-layer Warnings and Informational Messages to JSF [10.1.3.1]

ADF Business Components has a built-in warnings facility that complements the validation and exceptions features. This example illustrates how to configure a custom FacesPageLifecycleClass (described in more details in 10.5.4.1 Globally Customizing the ADF Page Lifecycle of the ADF Developer's Guide for Forms/4GL Developers) which registers itself as the JboExceptionHandler. This allows it to receive the handleWarning() notification when any business components warning is signalled in custom code. As illustrated in the DeptImpl class in the example, you signal a warning by constructing an instance of the JboWarning class and passing it to the addWarning() method of the ApplicationModule. To distinguish between a warning and a purely information message, the example introduces a subclass InformationalMessage that extends JboWarning and the handleWarning() method in the CustomFacesPageLifecycle class reports the warning as a FacesMessage with the appropriate severity. To experiment with the demo, run the TestPage.jspx page and try entering the value "ERROR" for the Dname field. That will cause an attribute-level validation to fail for that attribute. If you instead enter a Dname value of "WARN", then you'll see a warning reported. And if you simply make a change and save it successfully, you'll see a purely informational message reported.


 

100.JSF Parameter Form to Invoke a Stored Procedure [10.1.3.1]

The example illustrates how to create a JSF parameter form for calling a PL/SQL stored procedure. You'll need to run the supplied CreatePLSQLPackages.sql script to create the PL/SQL package named example_pkg used by the demo. This package contains a single procedure do_something which accepts a string parameter, number parameter, and date parameter and inserts these values into a new row in the EXAMPLE_PKG_TABLE table. In the J2EE application, the stored procedure invocation is encapsulated inside the business service inside the custom application module method collectDataUsingStoredProcedure. It accepts one string parameter, one number parameter, and one date parameter. Internally the method calls the stored procedure using the helper routine described in section 25.5.2 Invoking Stored Procedure with Only IN Arguments of the developer's guide. This custom application module method is published on the client interface as described in section 8.4.1 How to Publish Custom Service Methods to Clients. The JSPX page in the ViewController project was created by dragging the collectDataUsingStoredProcedure from the Data Control Palette and dropping it onto the page as an ADF Parameter Form. The page defintion variables get automatically cleared after each page submit due to a navigation rule that redirects back to the same page. The table below the input form was created by dropping the data collection named ExamplePkgTable from the Data Control Palette as a read-only table. Both the view object attributes and the page definition variables are leveraging ADF UI control hints to supply translatable prompts and format masks.


 

99.Avoiding Clearing a View Object's Queried Rows at Rollback [10.1.3.2] 2006, Upd: 17-APR-2007

This example illustrates a technique to avoid having a view object's queried rows cleared on rollback. There are three view objects in the project, one named DeptView which is an entity-based view object, one named DeptViewNonEntityBased which is a read-only, non-entity-based view object, and one named TransientViewObject that is programmatically populated and not based on a query. For read-only SQL-based view objects and transient view objects, you can prevent a rollback from clearing the view row cache by overriding both the beforeRollback() and afterRollback() method and commenting out the call to super. For an entity-based view object, you need to override these two methods as well as call the setClearCacheOnRollback() method on the oracle.jbo.Transaction interface, passing false. Note that this technique applies only to queried rows and not to newly added rows. This is due to the fact that during a rollback, as noted in the state diagram in section 9.2.5 Understanding Entity Objects Row States of the ADF Developer's Guide for Forms/4GL Developers, any entity object with 'New' status is removed (which transitions its status to 'Dead'). Note that the TransientViewObject is populated by the prepareSession() method of the application module, and that on its "Tuning" panel in the view object editor it is set to never query rows by using the "No Rows" setting in the "Retrieve From Database" section. This is equates to declaratively setting the max fetch size of the view object to zero.


 

98.Entity Object Lightweight Event Publish and Subscribe [10.1.3.1]

This example illustrates one way to use the lightweight JavaBeans event publish/subscribe mechanism that ADF Business Components supports for entity objects. The Dept entity in the project has published an event named OnDnameOrLocChanged. When you define a new event on the Publish tab of the Entity Object Editor, you indicate zero or more entity attributes that will be delivered as part of the event "payload" to any subscribed listeners. The event name is user-defined and your code decides when it will fire by calling the automatically generated method of the same named as the event. In this case, looking in the DeptImpl.java class, you can see that I've added a call to this OnDnameOrLocChanged() method inside the setDname() and setLoc methods. When you publish an event, in addition to the generated method used to fire the event, JDeveloper also generates code into a custom Entity Definition class for the entity publishing the event. If you look in the DeptDefImpl.java, you'll see generated methods to addOnDnameOrLocChangedListener() and removeOnDnameOrLocChangedListener. Other entities that want to subscribe to the event can do so programmatically by looking up the entity definition object of the publishing entity, casting it to the more specific custom entity definition class name, and then calling the addEventNameListener() method. The Emp entity in the demo declaratively subscribes to the OnDnameOrLocChanged event, indicating that the event should be delivered to all associated Emp entities based on a particular association that relates it to the publishing entity. Note that the method to be invoked to receive the notification must have a signature that matches the number, type, and order of the attributes delivered in the payload of the published event. Otherwise, you can choose to have the event only delivered to entities that have programmatically registered to receive the event using the methods mentioned above. If you test the AppModule application module and try changing the value of the Loc or Dname attribute of a department, you can observe in the JDeveloper Log window that the associated Emp entities in that department receive the notification.


 

97.Force View-Object Attribute Default to Override Entity Default [10.1.3.1]

By design, if a view object attributes supplies a declarative default value, it will be used as long as the underlying entity object attribute (if there is one) has not already defaulted the attribute to some non-null value. If you want to force a view-object-attribute-level default to always be used, even if the underlying entity object default has been provided, then this example illustrates a MyViewRowImplframework extension class that will achieve that. The DeptView view object in the example indicates that it should use the MyViewRowImpl class as its view row implementation class. The Dept entity object supplies default values for its Loc and Dname attributes, and the DeptView view object specifies a further view-object-attribute-level default value for the Loc attribute as well. You can use the ADF Business Components tester to try creating a new row to observe the behavior.


 

96.Sortable Transient View Object [10.1.3.3] 2006, Upd: 01-OCT-2007

This example illustrates a technique to override the applySortCriteria() method in a custom ADF BC data control to call setSortBy() on the iterator binding's underlying view object instance instead of the default of calling setOrderByClause(). The effect is that this leverages the view object's built-in support for performing in-memory sorting described in more detail in section 27.5.2 Sorting View Object Rows In Memory in the ADF Developer's Guide for Forms/4GL Developers. The ViewController project contains a custom subclass of the ADF BC data control, a custom subclass of the ADF BC Data Control Factory, and a reference to this factory in the DataBindings.cpx file. The CountryList view object retrieves its data from the companion CountryList.properties file. When you run the CountryList.jspx page, try clicking the table headings to sort ascending or descending by the CountryCode or the Description. While not required for the in-memory sorting example, the workspace also includes a few classes required if you don't want your application module to make any database connection at all. The NoDatabaseConnectionApplicationPoolImpl class that subclasses the default application module pool implementation to return null in a few strategic places to avoid the application module's connection to the database. The custom database transaction factory class NoDatabaseConnectionDatabaseTransactionFactory is configured to be used by setting the TransactionFactory property of the configuration, and it creates an instance of the custom NoDatabaseConnectionDBTransactionImpl2 class which overrides the doRollback() method to do nothing.


 

95.Change Preferred UI Locale with a Button in the Page [10.1.3.1] 2006, Upd: 07-MAR-2007

This example illustrates a technique to allow the user to toggle the preferred UI locale between English and Italian by pressing a button in the UI. The CustomFacesPageLifecycle class is a custom ADF Faces page lifecycle class that overrides the prepareRender phase of the ADF page lifecycle to adjust the locale of the JSF UI View Root (from which the current user's preferred locale is derived for the rest of ADF at runtime). For more details about how its configured in the project see 10.5.4.1 Globally Customizing the ADF Page Lifecycle of the ADF Developer's Guide for Forms/4GL Developers. It references the App managed bean to see what the user's preferred locale is. In the overridden prepareRender method, if App.preferredLocale is different from the current UI View Root's locale, then the method sets the locale of the view to the preferred locale before calling super.prepareRender. If it ends up changing the locale, it also forces any List Binding objects with a translatable label for their null entry (like "<No Department>") to have their list of valid values recalculated so the null entry will render in the new current locale. The TestPage.java backing bean sets the value of the App.preferredLocale to either ENGLISH or ITALIAN depending on the button you click. Notice that the JSF resource-bundle-based message strings change, as well as the ADF BC component UI hints that supply the strings for the table column titles and field prompts. Also, the AnotherPage.jspx page allows the user to change the value of a transient number attribute that was added to the entity object. The format mask of #0.00 is specified as part of the UI control hints at the entity object level and you can see that when in Italian a number like 3.45 is presented and edited using the locale-appropriate decimal symbol 3,45. The regular JSP page RegularJSPPageNotUsingJSF.jspx in the project illustrates how a regular JSP page might test and set the JSF managed bean that holds the user's preferred locale setting. This might be interesting to understand if you are trying to allow the user to set their preferred language from a regular JSP acting as a login page in an otherwise-JSF-based application.


 

94.View Link Accessor Driving Details from a Parameterized Table Function [10.1.3]

This example contains two read-only view objects in its Model project, one named MasterView and the other named ListBasedOnTableFunction. The former is a simple SELECT from DUAL that unions two rows of dummy data. The first row has the value "D" for its LIST_TYPE column, and the second row has the value "E". The ListForMasterRow view link defines a link between the master views ListType attribute and an attribute in the detail view object (which one doesn't actually matter), and it contains a custom view link SQL WHERE clause of simply "1 = 1". The ListBasedOnTableFunction view object defines a named bind variable Bind_ListType that has exactly the same name as the bind variable that the framework will automatically add for the view link. The expert-mode SQL statement for this view object references this bind variable as the argument to the GET_NAME_VALUE_LIST() PL/SQL function whose invocation it wraps in a TABLE() operator to treat the table-valued function result as if it were a table of data. The CreateTypesAndFunctions.sql script in the Model project creates the NAME_VALUE_TYPE object type, the NAME_VALUE_LIST type, and the GET_NAME_VALUE_LIST() function. The function is written to return a list of (Dname,Deptno) pairs from the DEPT table if the value passed in is 'D' and a list of (Ename,Empno) pairs if the value passed in is 'E'. Of course, the implementation of the function could be arbitrarily more interesting and dynamic without affecting the view object. The ViewController project contains a simple JSF page with a tree control displaying the two rows in the master view and their parameterized detail rows (which are a function of the value of the ListType attribute in each master row). The SwingView project contains a simple Panel1 panel with a similar Swing tree control showing the same thing.


 

93.Entity and View Object Based on Web Service [10.1.3]

This example contains two separate workspaces DeptADFBCWebService and EntityAndViewBasedOnWebService. The former contains two projects. The first is named Project and contains a simple DeptService application module, and a default Dept entity object, and entity-based DeptView view object. The application module has custom methods on its client interface like retrieveDepartmentData(), estimateCount(), findDepartmentByDeptno(), insertDepartment(), updateDepartment(), mergeDepartment(), and deleteDepartmentByDeptno(). The DeptService application module has been published as a J2EE Web Service as described in section 33.4 Publishing Application Modules as Web Services of the ADF Dev Guide. The second project in the DeptADFBCWebService workspace is a Tests project that contains JUnit tests to test both the application module's local client interface as well as testing the deployed web service. The tests should all succeed if you have run the supplied CreateEmpAndDeptTables.sql in the SCOTT account. The WAR deployment profile in the Project project deploys the web service to an external OC4J instance, which you can launch most easily by running the start_oc4j batch file (or shell script) in the ./jdev/bin subdirectory of your JDeveloper installation home directory. After deploying, you can test the web service by pointing your browser at the URL http://localhost:8888/DepartmentServices/DeptServiceSoapHttpPort. Note that the web service unit test fixture makes use of a web service proxy class named DeptServiceSoapHttpPortClient that was generated using JDeveloper's Web Service Proxy wizard, using the WSDL URL of http://localhost:8888/DepartmentServices/DeptServiceSoapHttpPort?WSDL The second EntityAndViewBasedOnWebService workspace contains an HRModule application module, and default entity objects and view objects for the DEPT and EMP tables. The DeptImpl.java has overridden appropriate methods in a way similar to what is described in section 26.4 Basing an Entity Object on a PL/SQL Package API of the ADF Dev Guide to have this Dept entity based on a web service. Similarly, the DeptViewImpl.java class has overridden appropriate methods, similar to the technique described in section 27.8.4 How to Create a View Object on a REF CURSOR of the guide. When you use the Business Components Tester to test the HRModule -- and you make sure you have the webservice in the other workspace deployed and currently running -- you can work with the data in the EmpView and DeptView view object instances. When the data is read for the DeptView it will pull it in from the underlying web service. If you update the data for an existing department, create a new department, or delete an existing department, the changes are saved back using the web service in the other workspace. Also try using simple view criteria in the tester to search for department rows in the DeptView. That should work, too.


 

92.Dynamic, Data-Driven JSF Parameter Form [10.1.3]

This example illustrates one technique for implementing a dynamic, data-driven parameter form. The Database project in the workspace contains CreateTables.sql and InsertData.sql scripts that define and populate four simple tables: PARAMETER_FORM_DEFINITION, PARAMETER_DEFINITION, PARAMETER_CHOICES, and PARAMETER_FORM_ITEM_SET. See the database diagram in that project for a visual view of how they are related. The insert data script populates some sample data for two parameter forms named "Form1" and "Form2", each of which has some collection of parameters in its form item set. The ParameterFormItems view object queries the list of parameters for a given parameter form by its form id, which is passed in as a named bind variable (TheFormId). There is a view link defined between the ParameterFormItems view object and the ParameterChoicesView that enables a view link accessor attribute named ParameterChoices in each row of the ParameterFormItems view object's results. In the ViewController project, you will find three pages. The TestParameterForm.jspx page allows you to select any of the defined parameter forms and test it by setting the #{processScope.ParameterFormId} attribute to the parameter form you've selected and navigating to the DynamicParameterForm.jspx page. That page is the real meat of the example. It includes a ADFM tree binding to expose the hierarchical collection of data for the ParameterFormItems and its collection of available choices (via the ParameterChoices view link accessor attribute). The page definition for this page includes an invokeAction that triggers the firing of an ExecuteWithParams action binding when the page is not handling a post-back (RefreshCondition="#{adfFacesContext.postback==false}"). This allows the ParameterFormItems view object's TheFormId named bind variable to be declaratively set to the value in the #{processScope.ParameterFormId} attribute that defines which data-driven parameter form to show. The page defines uses an <af:forEach> to iterate over the parameter form items. Inside this loop, it uses an <af:switcher> based on the value of the DisplayType attribute of the parameter definition. The switcher determines whether to display the item as an inputText, a selectOneChoice (i.e. dropdown list), or a selectOneRadio (i.e. radio group) depending on whether the DisplayType of each parameter is 'I', 'S', or 'R' respectively. In the case of rendering the parameter as a dropdown list or radio group, an inner <af:forEach> accesses the nested collection of available choices defined to populate the list. The last part of the example involves understanding where the user's entered values are posted and stored. This is handled by a transient view object attribute named UserValue that has been added to the ParameterFormValues view object. The ShowUserEnteredValues.jspx page renders the parameters along with the user-entered values, and the DynamicParameterForm.java backing bean class contains code that illustrates how you would access the values of the users parameter item values in the backing bean if needed. For extra credit, you can use the ADF Business Components Tester on the ParameterFormModule to maintain the parameter form metadata that drives the parameter forms, adding a new form, new items, or new item choices as needed.


 

91.Reusing Databound ADF Swing Panels with Different View Object Instances Using Model Parameters [10.1.3]

The EmployeePanel in this example was created using the Panel wizard in the ADF Swing category in the New Gallery. Then, I manually parameterized its data control and iterator name using two page definition parameters named dcParam and rsiParam (where 'rsi' is short for RowSetIterator). The example includes four other ADF Swing panels that then reuse the EmployeePanel, each passing in appropriate values for the dcParam and rsiParam parameters. To drop an instance of a reusable ADF Swing panel, simply select the Component Palette page named ADF Swing Regions and you'll see that the EmployeePanel automatically appears there as a reusable component. When you drag/drop the EmployeePanel onto a panel where you want to use it, JDeveloper pops up a dialog asking you to fill in EL expressions to give appropriate values for the panel's dcParam and rsiParam parameters. In this way, you can reuse the same panel with different view objects. You'll see a special "page" binding appear in the Executables section of the including panel's page definition, along with metadata capturing the EL expressions you've entered. The example features a Panel1 panel that reuses EmployeePanel to display the results of the data collection named EmpView1 in TestModule1DataControl. A Panel2 panel reuses the EmployeePanel panel bound to the data collection named AllEmployees in the TestModule2DataControl, based on a different application module. The Panel3 panel illustrates that you can reuse the EmployeePanel for a data collection that is a view-linked detail view object instance, in particular the EmployeesInDepartment data collection in the TestModule2DataControl. And finally, the Panel4 panel shows that you can reuse the EmployeesPanel bound to a view object that's completely different than the original one that was designed to create it, provided that it has the expected attribute names with the expected data types. In this case, it is bound to the data collection named EmployeesReadOnly in the TestModule2DataControl, an instance of the non-entity-based (and hence read-only) view object of the same name.


 

90.Avoiding Dirtying the ADF Model Transaction When Transient Attributes are Set [10.1.3]

At the ADF Model data binding layer, there is no distinction between attributes that are transient or persistent. When any attribute's value is changed through an ADFM binding, the ADFM-layer transaction is marked as dirty. This can have the unwanted side-effect of enabling the JClient navigation bar's Commit and Rollback buttons even if the only thing the end-user did was to change the value of a transient field, potentially leading to end-user confusion. This JClient example illustrates a DeptView to which an additional transient Boolean attribute named Selected has been added. The View project in the example illustrates a custom ADF Business Components data control class (MyCustomADFBCDataControl) that extends the default ADFBC data control class (JUApplication). The custom version overrides the setTransactionModified() method to avoid dirtying the transaction unless the transaction related to the underlying application module is actually dirty. The companion MyCustomDataControlFactoryImpl is required to instantiate the custom data control class, and the DataBindings.cpx file references the fully-qualified class name of the custom data control factory class in the FactoryClass property of the <BC4JDataControl> element in the <dataControlUsages section of that file. Run the Panel1 class to see the code in action. Clicking on the Selected? checkbox toggles the value of the transient flag, as visible by the message that the setSelected() method in the custom view row class prints to the console, but the JClient toolbar does not enable the Commit or Rollback buttons until you actually modify some persistent attributes.


 

89.Maintaining Many-to-Many Intersection Rows in a Multiselect Table [10.1.3, SRDemo schema]

This example illustrates a very model-centric approach for managing the rows in an intersection table of a many-to-many relationship using a multi-select table. It is based on the tables in the SRDemo schema USERS, PRODUCTS, EXPERTISE_AREAS. The Staff view object is an entity-based view object based on the User entity object that has a WHERE clause to retrieve only the users having a USER_ROLE is either 'technician' or 'manager'. The ProductExpertiseAreas is an entity-based, expert-mode view object whose SQL statement is crafted to use outer joins to return exactly one row for each available product. The view object has the Product entity object as its primary entity usage, and has ExpertiseArea as a secondary, reference entity usage. It defines a named bind variable Bind_UserId that is consciously named exactly the same as the system bind variable the framework will add for the view link between Staff and ProductExpertiseAreas (based on the UserId). That view link has a customized view link SQL clause to allow the USER_ID to be NULL so that the detail rowset retains a row for every product, even when the current user does not have expertise for that product currently. Due to the outer join, rows retrieved retrieved in the ProductExpertiseAreas view object will have a non-null ExpertiseArea entity row part when the current user has expertise area in that product. Conversely, if the current user does not have expertise in a given product, the ExpertiseArea entity row part will be a blank entity row. To simplify the client, we introduce a transient Boolean-valued attribute on the ProductExpertiseAreas view object named HasExpertise. We override the getHasExpertise() and setHasExpertise() methods in the view row class to handle retrieving and setting this transient attribute. The setter method handles either creating a new ExpertiseArea instance corresponding to the current userId and prodId combination, or removing an existing entity row, depending on whether HasExpertise is being toggled on or off. Implementing a model-centric solution gives three interesting benefits: (1) You can test and debug the complete functionality just using the ADF Busines Components Tester, (2) UI can just bind a checkbox to the Boolean HasExpertise property, and the functionality works the same in JSF, JSP, or Swing. The ViewController project contains a simple JSF page that displays a table containing a selectBooleanCheckbox bound directly to the HasExpertise attribute. In other words, it is not using a special tableSelectMany component in its selection facet. The checkbox is just a part of the "data" in each row.

Note: This example uses the SRDEMO schema from the SRDemo sample application.
 

88.Dynamically-Updating JSP Graph in JSF Page [10.1.3.2] 2006, Upd: 25-JUL-2007

This example illustrates a JSF page with a dynamically-updating graph. In the 10.1.3 release, ADF supports creating graphs and the corresponding graph binding, however the graph tag is not yet a JSF UIComponent. The PageWithDataAndGraph.jspx page in this example illustrates how you can still use the <graph:Graph> tag inside the JSF page by wrapping it with an <f:verbatim> tag. In addition, to allow this non-JSF component to still be updated dynamically (AJAX-style) you further wrap the <f:verbatim> tag by a panel like panelGroup. The backing bean for the page illustrates how to allow an updateable UIComponent in a table to trigger partial page rendering for other elements in the page by programmatically calling the ADF Faces addPartialTarget API. I initially created the graph tag by creating a regular (i.e. non-JSF) JSPX page, and dropping the EmployeesInDepartment data collection from the Data Control Palette as a Graph, then I copied the graph tag and its corresponding tag namespace to the page I wanted to include it in. Lastly, I then copied the Graph binding into the page definition of the target page, and ensured that its binding id was unique. After renaming the graph binding to be unique, I updated the EL expression in the Graph tag's data attribute to reference the renamed graph binding. Finally, I edited the chart's visual properties by double-clicking on the BIGraphDef1.xml node in the navigator and using the graph definition editor, the Structure Window, and the Property Inspector. Also of interest is that the chart binding is setup to graph a transient entity object attribute called TotalComp which simply is the sum of the Sal and Comp attributes to provide an employees total compensation. Notice that you can edit the Sal or Comm values in the table and the graph dynamically updates. You can also use the navigation list or the (Next) / (Previous) buttons to change the department, and the graph updates to reflect the employees in the current department. The Emp entity in the Model project uses the generic, automatic attribute recalculation logic explained in section 26.8 Implementing Automatic Attribute Recalculation of the ADF Developers Guide for Forms/4GL Developers, and implemented in the SRDemo Sample ADFBC Version.


 

87.Expose Original Attribute Values in Pending Transaction [10.1.3]

Section 9.9 How to Access Original Attribute Values in the ADF Developers Guide for Forms/4GL Developers explains the getPostedAttribute() API you can use to access the value of any attribute as it existed at the beginning of the current transaction. This example illustrates a technique for exposing that API in a generic way to the ADF binding layer so that your application pages can display that original value to the end-user. This could come in handy to allow the user to visually review their pending changes in the transaction before finally confirming to save the changes with a (Commit) button. In the Model project, The technique involves: (1) exposing the getPostedAttribute() API as public in a CustomEntityImpl framework extension class since otherwise the method would be protected, (2) automatically adding a "shadow" attribute named OrigAttrName_orig for each attribute in the view object (in the overridden create() method of the CustomViewObjectImpl class, and (3) returning the original value of the appropriate underlying entity attribute using getPostedAttribute() in an overridden getAttributeInternal() method of the CustomViewRowImpl class. The Dept entity is configured to use the CustomEntityImpl and the DeptView view object is configured to use the CustomViewObjectImpl component class and the CustomViewRowImpl row class. In the ViewController project, the technique involves referencing the "_orig" attribute names in the EL expressions for the values of certain UIComponents. Try navigating through multiple rows in the DeptView and making changes to the Dname and or Loc attributes in any of them. As you scroll back and forth before issuing the final transaction commit, you will notice that the previous value of the changed attributes appear next to your modified values wherever you've modified them.


 

86.Registering a Customized Page Lifecycle as JSF Managed Bean [10.1.3]

This example illustrates an interesting technique (that I initially learned from the always-clever JHeadstart team). The CustomFacesPageLifecycle class is registered in the faces-config.xml file as an application-scoped managed bean named PageLifecycle (the name is arbitrary, of course). The CustomADFPhaseListener class is registered in the "Life Cycle" section of the faces-config.xml as well. Its overridden createPageLifecycle() method uses the EL helper class to return the custom page lifecycle class using the method EL.get("#{PageLifecycle}"). Why would you want to do this, you ask? The TestPage.jspx illustrates two simple examples (and there may be more). The (Some Button) on the page has its Action property set to the EL expression #{PageLifecycle.onButtonClicked}, illustrating that the custom lifecycle class (being EL-accessible) can have global helper routines like an action listener method. Another example is the Dname af:inputText fields whose Value property is set to the EL expression #{PageLifecycle.attributeBindingWrapper[bindings.Dname]}. This shows that the helper routines in the custom page lifecycle class can leverage a customized Map approach to effectively provide simple, one-argument callable methods. In this case, the getAttributeBindingWrapper map wraps the AttributeBinding passed in as an argument. The second of the two Dname inputText's shows that by wrapping the attribute binding in this way and setting the Disabled property to true, you can get an inputText that shows as a disabled field instead of a read-only label which is the default rendering of read-only inputText fields.


 

85.Uploading Contents of af:inputFile to a BLOB Column [10.1.3.3] 2006, Upd: 03-OCT-2007

Using ADF BC's support for the Oracle Intermedia ORDImage, ORDDoc, ORDAudio, and ORDVideo, you can simplify uploading, downloading, and displaying media and documents. However, since numerous users have asked for it, this example illustrates a simple JSF page with an inputFile component and the backing bean logic to handle inserting the contents of the uploaded file into a BLOB column in the database. Run the CreateTables.sql script to drop and create the simple UPLOADED_FILES table. Then, run the UploadFileToBlob.jspx page. Note that the page uses the af:form container with its usesUpload attribute set to true. Also notice that the inputFile control is bound to the backing bean property named fileInputComponent, allowing the backing bean to reference the UI component programmatically. The valueChangeListener on the inputFile is mapped via EL to the onFileUploaded() method in the backing bean. That method accesses the ExampleModule client interface of the ExampleModule application module, and invokes the saveUploadedFile() method on it. It passes in the file name, and a BlobDomain class representing the contents of the uploaded file. The (Upload File) button's action property is mapped via EL to the onUploadFileButtonClicked() method in the backing bean. This method either displays an error message if the filename to be uploaded is bad, or else causes the "Last File Files Uploaded" iterator to be re-executed to retrieve the latest list of the last file files uploaded (by any user). See Configuring ADF Faces File Uploading Servlet Parameters for information on some settings you might need to configure.
 

84.Declaratively Toggling Display of PanelBox Based on Radio Group Value [10.1.3]

This example illustrates a simple JSF page with a selectOneChoice and a selectOneRadio, each with its respective value bound to an Integer-valued backing bean property. The switcher controls use the respective property value to toggle the display of an appropriate PanelBox, and the partialTriggers property setup on the containing panelGroup component causes the panel to repaint when the value of the respective selectOneXXX component changes.


 

83.Dump Application Module Pooling Statistics Servlet [10.1.3]

This example illustrates a servlet that dumps application module pooling statistics and/or ADFBC database connection pooling statistics to the browser. The DumpPoolStatisticsServlet is configured in the web.xml to map to the URL /DumpPoolStatistics. The DumpConnectionPoolStatisticsServlet is configured in the web.xml to map to the URL /DumpConnectionPoolStatistics. In contrast to using a JSP page to dump these statistics, using servlets configured this way instead avoids engaging the ADF Binding Filter, the ADF Faces filter, or the ADF Faces servlet when viewing pooling statistics. Run the EditEmps.jspx and click (Next) or (Previous) a few times. Then click the "DumpPoolStatistics" and/or "DumpConnectionPoolingStatistics" links in the page to open a new browser window with the pooling statistics. Recall that if your ADF application using J2EE datasources instead of a JDBC URL connection, then you will be using your application server's connection pool instead of the ADFBC connection pool. In that case, the database connection pooling statistics won't appear using this mechanism. CAVEAT: the connection pools are named using the fully-qualified JDBC connection credentials, which includes the password. We recommend using the DumpConnectionPoolStatistics servlet with care in a production environment and not leaving the configured permanently (unless you protect access to it with a password using HTTP authentication).
 

82.Adding a Dynamic 'Valid' Attribute to View Objects [10.1.3]

This example illustrates an framework extension approach for adding a dynamic attribute named Valid to any view object whose value returns true if the primary entity usage in the row is valid, or false if it is invalid. The CustomViewObjectImpl class adds the dynamic attribute in its overridden create() method. The CustomViewRowImpl class overrides the getAttributeInternal() method to return the desired value for the dynamic attribute. The Emp entity object in the example has four different validation methods that enforce business rules like: (1) If Deptno=40, then Job must be SALESMAN or CLERK, (2) Salesmen in department 40 must have salary of 1500, (3) Clerks in department 40 must have salary 1000, and (4) Comm is not greater than Sal. The untitled1.jspx page in the ViewController project has a ADF Faces table and references the dynamic Valid attribute to highlight invalid rows in yellow using some appropriate EL expressions in the inlineStyle attribute of the fields in the table. The untitled1PageDef.xml file had to be hand-modified to include the dynamic Valid attribute in the AttrList of the EmpView table binding so that the EL expression used above of #{row.Valid} would be resolvable. And finally, the Untitled1PageController class is registered as a custom page controller for the untitled1.jspx page (by setting the ControllerClass attribute at the root of the page def XML document. This custom controller overrides the default way that the validateModelUpdates() phase of the ADF page lifecycle is implemented to force invalid rows to be revalidated. This works around Bug# 5396224, where clicking a second time on the ADF faces table's "Next" or "Previous" navigation link causes a validation error to not be reported again.
 

81.Refreshing Calling Page After Adding New Row in Popup Dialog [10.1.3]

This example illustrates one technique for causing the current page, containing a "Browse Employees" table, to refresh upon returning from a popup dialog wherein the user has added a new employee. The onReturnFromDialog() in the BrowseEmployees backing bean is configured as the ReturnListener for the button. It calls a refreshCurrentPage() helper method to accomplish the page refresh. It works in combination with setting the partialSubmit property and the useWindow properties to true on the (Add New Employee) button in the page. The onSaveNewEmployee() method is required for the ActionListener on the (Save New Employee) button since we want to conditionally return from the dialog, only when no errors occur during the execute operation on the "Commit" action binding. Using the declarative <af:returnActionListener>, we couldn't accomplish this conditional behavior. As a bonus, the example also illustrates edit and delete behavior as well. By choice, the add a new employee is performing an immediate commit, while the edit and delete operations need to be explicitly committed or rolled-back by the user.
 

80.Simple JSF Popup List of Values Page [10.1.3]

This example contains an "untitled1.jsp" page that uses a separate "pickDept.jsp" page as a popup List of Values (LOV) dialog page. The pickDept page includes <af:returnActionListener> and <af:setActionListener> as nested children components of the submit button. These cause the popup dialog page to return to the calling page and to set the selected value into the Deptno attribute binding that I've added to the pickDept page's page definition.
 

79.Setting First Row in New Page Current When Paging Through Table [10.1.3.3] 2006, Upd: 22-OCT-2007

This example contains an onRangeChanged() range-change listener method in the TestPage.java backing bean for the TestPage.jspx page. It uses a couple of lines of code to set the range starting row to the new starting row index (zero-based) passed in the RangeChangeEvent object, then sets the first row in the new range to be the current row. It also sets a requestScope attribute as a flag to allow the onSelectionChanged method to known whether or not it should ignore the firing of the normal ADF selection change listener or not. Note that the EmpView view object has its "Fill last page of rows when paging through rowset?" property set to false on the Tuning panel of the View Object editor.
 

78.Updating Form Fields When Using Immediate=True [10.1.3]

This example contains a DEPT-based view object presented in both a table and a form display. The (Create), (Delete), and (Rollback) buttons are set to have their immediate property to the value true which causes validation to be circumvented. There are two functionally-identical JSPX pages, one which programmatically calls resetValue() on the Faces UI components in the backing bean to cause their values to be refreshed, and the other which uses the <af:resetActionListener> to accomplish the same thing declaratively.
 

77.Using a View Object with SQLXML to Query Data from XML [10.1.3]

This example contains a DepartmentDataFromXML view object that uses the SQL XML support in Oracle 9i Release 2 (or later) to query the data from an XML document into a view object. The view object accepts the XML text in a named bind variable, and uses the xmltype() constructor to treat that XML text as an XML document. Then it uses the xmlsequence() operator to treat the results of extract()-ing the <ROWSET>/<ROW> elements from the XML document as individual rows of source data. Finally, it uses the table() operator in combination with the extractValue() operator to retrieve the data values from each row of <ROW> fragments, breaking out a DEPTNO, DNAME, and LOC value from the row. The TestPage.jspx in the ViewController project allows you to experiment with passing in different XML as the value of the bind variable.
 

76.Optionally F