This project contains an historical set of code samples relating to various versions of the Oracle Application Development Framework (ADF). Many of these samples where previously hosted on Java.net and will relate to various versions of ADF.
This repository is laid out with each sample expanded in it's own subdirectory under the root /src directory. This allows you to browse the code without downloading. Each sample is also available as a downloadable zip from the releases area
- 11g Dynamic JDBC Credentials for Model 1, Struts, Trinidad, and ADF Faces Rich Client [11.1.1.0.0] 06-AUG-2008
- This is an 11g production update of one of my most frequently downloaded examples (Dynamic JDBC Credentials, #14). There are four separate workspaces, one for each of the supported ways you might build a web application using ADF:
DynamicCredentialsNoController.jwsis a "Model 1" style application with no controller layer;DynamicCredentialsStruts.jwsis Struts-based;DynamicCredentialsTrinidad.jwsis a 10.1.3 ADF Faces application that's been migrated to use the Apache Trinidad components; andDynamicCredentialsRichFaces.jwsuses the new ADF Faces Rich Client components that are new in 11g. Each project references the sameModelproject andFwkExtensionsproject. The generic framework extension classes involved in implementing the solution live in theFwkExtensionsproject. TheModelproject contains the simple ADFBC components used in the example: aTestModuleapplication module with a singleDeptViewVO instance of aDeptViewview object based on theDEPTtable in the SCOTT schema. While updating the example for 11g, I took the liberty of using two new features that allowed me to simplify and streamline the implementation. The first of these was using the newErrorHandlerClassattribute on the root<Application>element of theDataBindings.cpxfile in each of the client web projects in order to register a custom ADFM error handler implementation (test.DynamicJDBCErrorHandlerImpl). This error handler is designed to notice theDMLExceptionthrown by a failed database connection attempt (due to incorrect username/password combination), and it throws that particular exception rather than simply caching it on the binding container. The second new feature employed is the ability to register a global customization to the ADF Page lifecycle by using aMETA-INF/adf-settings.xmlfile in each client web project. Each project registers thetest.DynamicJDBCPagePhaseListenerin order to conditonally execute some custom logic before the ADF "prepare model" phase of the lifecycle. This custom logic references the data controls in the current page definition, causing them to be checked out of the AM pool (if they were not already checked out during the current lifecycle) before the JSF page rendering begins. This allows the error handling code to catch the failed connection attempt in time to redirect the user to the login page before the rendering phase begins. The web.xml file for each ViewController project contains a context parameter (RedirectToLogin) that defines the login page to redirect to for that particular web application. The JSF project contains a second context parameterFacesURLPatternas well. Due to Bug# 5080057, setting thejbo.ampool.sessioncookiefactoryclassproperty in the configuration is not correctly saved to thebc4j.xcfgfile. So, in order to configure a custom session cookie factory class as required to repurpose the code in this example in your own projects, you'll need to hand-edit thebc4j.xcfgfile to insert the child element<jbo.ampool.sessioncookiefactoryclass>test.DynamicJDBCSessionCookieFactory</jbo.ampool.sessioncookiefactoryclass>inside the appropriate<AppModuleConfig>element for the configuration in question.
- This is an 11g production update of one of my most frequently downloaded examples (Dynamic JDBC Credentials, #14). There are four separate workspaces, one for each of the supported ways you might build a web application using ADF:
- Example of Accessing Bindings and BindingContainer as Managed Properties in JSF Backing Bean [10.1.3 EA1]
- This simple example has a single Example.jsp page containing an ADF Faces read-only table bound to the DeptView1 iterator, and a few buttons. One button was created by dropping the myCustomMethod() of the application module onto the visual editor as a command button and is totally declarative. That action created me the necessary action binding to invoke the method. The parameter value being passed in is provided by an EL expression property of the action binding parameter in the page definition. The other two buttons are invoking action methods in the MyManagedBean class. That managed bean is a simple POJO class that is declaratively configured in the faces-config.xml to inject a "bindingContainer" and a "myCustomMethod" property of appropriate type, using appropriate EL expressions. This means I can refer to these in my action method in an easy way. The example simply outputs the result of invoking the application module method into an output text field in the page. NOTE: We're planning to make this more easy and automatic for 10.1.3 production!
- Accessing Array-Valued Bean Properties from a Row in JSTL
- This example illustrates a model-one style JSP page (e.g. no controller layer) that uses JSTL to render the java.util.List-valued results of invoking the findNominalRecords() method in the JavaBean-based data control based on the "Service" bean in the "Model" project. The results are just a couple of hard-coded NominalRecord beans, but the point of the example is illustrating the JSTL syntax used to refer to the underlying bean properties in a row through the ADF binding layer when necessary. Normally we handle nested collections as accessors, but this example illustrates an alternative that works for JavaBean-based data binding that in some cases might be a little simpler. Run the TestPage.jsp page to see it in action.
- 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 theBrowseEmployeesbacking bean is configured as theReturnListenerfor the button. It calls arefreshCurrentPage()helper method to accomplish the page refresh. It works in combination with setting thepartialSubmitproperty and theuseWindowproperties totrueon the (Add New Employee) button in the page. TheonSaveNewEmployee()method is required for theActionListeneron 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.
- 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
- 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.jspxbuilt 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 JSFFacesMessagein case theEmployeesResultsIteratorreturns either no rows or too many rows (with the limit hard-coded for this example to 10). TheSearchPagebacking bean inherits from theBackingBeanBaseclass 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). Therenderedattribute on theaf:tableshowing the search results in theSearchPage.jspxuses an EL expression to cause the table to render only when the number of rows found is between 1 and the maximum allowed (10).
- This example illustrates a
- ADFBC Application With No Database Connection [11.1.1.1, SCOTT schema] 01-SEP-2009
- This example illustrates a technique for creating an application module that does not use a database connection. The only reason you might want to do this is that you are exclusively using programmatic view objects and entity objects, which might be an infrequent scenario, but does come up from time to time. The example illustrates a number of lesser-used framework extension classes. The
NoDatabaseApplicationPoolImplis a custom application module pool implementation class. TheNonDatabaseConnectionStrategyis a custom connection strategy class . TheCustomSessionImplis a custom session class, which returns a custom transaction handler factory. TheCustomTxnHandlerFactoryImplis a custom transaction handler factory used to return an instance of the customCustomTxnHandlerImplclass, which is a custom transaction handler implementation. TheSessionClassconfiguration property is set to the name of the custom session implementation class, which in turn bootstraps the custom transaction handler factory and custom transaction handler. ThePoolClassNameconfiguration property is set to the name of the custom application module pool implementation class. This class overrides theisSupportsPassivation()method to return false, indicating to the runtime that this particular application module pool does not support passivation. Thejbo.ampool.connectionstrategyclassconfiguration property is set to the name of the custom connection strategy class which overrides thecreateApplicationModule()method to set some key properties in the environment hashmap before calling super. TheStaticVOis a static view object that returns rows whose data is in theModelBundle.propertiesfile.
- This example illustrates a technique for creating an application module that does not use a database connection. The only reason you might want to do this is that you are exclusively using programmatic view objects and entity objects, which might be an infrequent scenario, but does come up from time to time. The example illustrates a number of lesser-used framework extension classes. The
- Simple Extension Using ADF BC Design Time Objects API [10.1.3]
- This example contains a simple JDeveloper extension called EmpDeptExampleExtension patterned after the JDeveloper Extension SDK's "FirstSample" example. It adds a simple menu option to the right-mouse menu called "Create Emp/Dept Objects..." When you choose this option, it uses the API's in the oracle.jbo.dt.objects package to create entity objects Dept and Emp for DEPT and EMP tables in the SCOTT schema. It then creates an association between them, default view objects for the entity objects, a view link between the two view objects, an application module, and view object instances and a view link instance in its data model. Required installation steps include: (1) Ensure you have installed the "Extensions SDK" from the JDeveloper "Check for Updates..." center, (2) Making sure you've defined a connection named "scott", (3) Editing the "ADFBC DT Library" library definition to point to the JDEVHOME/jdev/extensions/oracle.BC4J.10.1.3.jar in your JDeveloper 10.1.3 installation, (4) Editing the target JAR file name in the EmpDeptExampleExtension.deploy deployment profile so that the JAR (whose name you should leave as-is) gets deployed to the JDEVHOME/jdev/extensions directory in your JDeveloper 10.1.3 installation. Then, after deploying the deployment profile to produce the extension JAR file, exiting JDeveloper, and restarting, you should have an additional menu pick on the context menu in the Application Navigator. Choosing this menu option in an empty project will create the objects described above which you can immediately test using the Business Components Browser.
- ADFDetectWindowResize
- Customzing ADF Faces Convert Number Detail Error Message from a Message Bundle [10.1.3.2] 05-MAR-07
- The
af:convertNumbertag 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 namedconvertNumberMessageDetail. In order to reference a resource bundle message, normally you would expect to be able to use anf:loadBundletag 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 withloadBundleare only available during the page rendering phase, but not during the validation phase. So, in order to drive theconvertNumberMessageDetailfrom a message bundle, I needed to borrow some of the code from the JSF reference implementation'sloadBundleTagclass that exposes a resource bundle as a Map, and I put it in theAppliationMessageMapmanaged bean class in this example. I've configured that to be a session-scoped managed bean and configured itsbasenamemanaged property to have the valueview.resources.JSFMessagesinfaces-config.xml. This allows me to reference my custom error message for "Field 2" in the demo, in itsf:convertNumbertag'sconvertNumberMessageDetailattribute using the EL expressionAppMessages.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.
- The
- ADFJSFSuccessFinished
- ADFJSFSuccessStart
- ADF and JSF Utility Classes [10.1.3]
- This is a workspace containing a project with JSFUtils.java and ADFJSFUtils.java utility classes that have some useful static methods for building JSF/ADF applications.
- ADFLoggingTemplates
- ADFMobileBrowsingThroughSwiping
- ADFMobileErrorHandling
- ADFMobileLocalDatabase
- ADFMobileRowCurrrency
- Passing Multiple Selected Keys from Tree, Table, and TreeTable to Application Module Method [11.1.1.6.0] 07-NOV-2008, Upd: 02-NOV-2011
- A common requirement in pages containing table, tree, or treeTable components is to allow the user to select multiple rows and then carry out some operation on the selected rows. This example illustrates the best-practice declarative approach to accomplish this. First of all, notice that the code that processes the rows is correctly encapsulated inside the
AppModuleapplication module's custom java class, and that both theprocessSelectedEmployees()andprocessSelectedDepartments()methods are exposed on the client interface so they are available for declarative data binding in the data control palette. Notice they these accept ajava.util.Set(which we expect at runtime to containoracle.jbo.Keyobjects. The reason we're not using Java generics likeSet<Key>in the method signature is that the ADFBC client interface mechanism does not yet support using generics in the method signature. The implementation of these methods processes the set passed in, casting each object in the set to aKeyand then using thefindByKey()on the appropriate view object instance in the data model to find the row by its key and then act on it. There are two pages in the demoview1.jspxandview2.jspx. Start by looking at theview2.jspxpage, which includes a table ofDeptViewrows from the view object instance namedDepartments. Importantly, notice that to enable the multi-select on the table three required steps have been taken: (1) TherowSelectionattribute is set to "multiple", (2) theselectedRowKeysattribute has been removed, and (3) the selectionListener has been removed. Steps (2) and (3) are automatically setup to support single-row selection and must be removed whenever you enable multiple row selection in the table, or else the multiple selection will not work correctly. The customprocessSelectedDepartmentsmethod was dropped from the Data Control Palette onto the page as a button, and the EL expression for the method argument is set to${View2.selectedAdfRowKeys[View2.myTable]}which makes use of a generic helper backing bean that the ViewController project includes to simplify working with multiple selection in tables, trees, and treeTables. TheView2backing bean is defined inadfc-config.xmland rather than using a specific backing bean class for the View2 page, its using the generic helper classMultiSelectSupportBackingBean. That bean conveniently contains a property namedmyTableof typeRichTablewhich is designed to be referenced by thebindingproperty of a page containing a RichTable where you'd like to perform some processing on its multiple-selection. In fact, if you look at thebindingproperty of theaf:tablecomponent in theview2.jspxpage, you'll see that it's set to this property using the expression#{View2.myTable}. So the${View2.selectedAdfRowKeys[View2.myTable]}expression used as the parameter value of the declarative method action binding accesses theselectedAdfRowKeysMap-valued property of the backing bean, passing theView2.myTableinstance of the RichTable on that page as the map key. As you can see in theMultiSelectSupportBackingBeanclass, theselectedAdfRowKeysis an anonymous subclass ofjava.util.Hashmapthat overrides theget()method to perform a custom operation when the EL expression evaluator tries to access the map's properties. In effect, this pattern allows us to introduce something that works like a custom function that accepts one argument into our EL expressions. In this case, the argument is the UI component for which you'd like a Set of selected Keys. Theview1.jspxpage shows the same genericMultiSelectSupportBackingBeanclass in use as the page'sView1backing bean, and three different instances of method action bindings in the page definition forview1.jspxare used to invoke theprocessSelectedEmployees()custom method with the appropriate UI component passed as the "argument" to the EL expression to reference the Set of selected Keys. A last thing to note about the example is how theEmployeeHierarchyview object instance in the data model is setup. Notice that theEmpViewview object defines a view criteria namedEmployeesWithNoManagerthat finds employees that have aMgrattribute equal to null. TheEmployeeHierarchyview object instance was added to the data model in the application module editor, then I used the (Edit) button just above the Data Model tree to edit that view object instance to apply theEmployeesWithNoManagerview criteria to it. This means that initially the view object will only show employees with no manager (e.g. KING). Then, due to the presence of thetest.model.links.Managesview link betweenEmpViewand itself, based on theEmpno->Mgrrelationship, the direct reports of the employees with no manager will appear as children in the tree and treeTable due to the related tree binding rules that uses theDirectReportsview link accessor attribute to access the nested child collections of direct reports rows at each recursive level. Notice as well that there are no view link instances required in the data model to work with the tree or treeTable since the related tree bindings use the view link accessor attributes to get detail information, and not data model view instances linked via view link instances in the data model. I highly recommend reading section 35.1.3 Understanding View Link Accessors Versus Data Model View Link Instances to help understand the important distinction.
- A common requirement in pages containing table, tree, or treeTable components is to allow the user to select multiple rows and then carry out some operation on the selected rows. This example illustrates the best-practice declarative approach to accomplish this. First of all, notice that the code that processes the rows is correctly encapsulated inside the
- ADFToyStoreJSF
- ADF Web Application with Component Substitution [10.1.3.4] 06-OCT-2008
- This example illustrates how to use the techniques outlined in section 25.10 Substituting Extended Components In a Delivered Applicationof the ADF Developer's Guide for Forms/4GL Developers to substitute extended components into a running application. The
BaseADFWebAppworkspace in the download contains a simple, one-page DeptView data entry form. ItsModelproject contains atest.Deptentity object,test.DeptViewview object, and atest.AppModuleapplication module containing an instanceDeptView1oftest.DeptView. ItsViewControllerproject contains aDepartments.jspxpage with the data entry form. TheModelproject contains a ADFBC deployment profile to deploy the ADFBC components as a simple java archive. TheExtendsAndSubstitutesworkspace contains aExtendsProjectproject which has imported thetest.Deptentity from the simple ADFBC JAR archive created in the other workspace'sModelproject. It then has created an extended entity objectextendsproject.DeptExwhich extends thetest.Deptentity, overrides itsLocattribute, and adds an attribute-level validator onLocto prevent the value from being the single, uppercase letter "X". TheExtendsProject.jpxdefines the component substitution metadata saying thatdept.Deptshould be substituted withextendsproject.DeptEx. This metadata was defined using the Substitutions detail panel of the Business Components project properties. In addition, theExtends Projectcontains a fileExtendsProject.cpxto workaround bug 6629321, whose contents can be anything as long as it is a well-formed XML file. In the example, the workaround file contains the single element <workaround_for_bug_6629321/>. TheExtendsProjectproject contains another ADFBC deployment profile to deploy the extended components as a simple JAR archive file. Finally, theViewControllerproject adds the runtime Java VM argument in its Run/Debug profile of-DFactory-Substitution-List=ExtendsProjectto use theExtendsProject.jpxfile found in the classpath at runtime as the component substitution list. TheViewControllerproject also includes a project-level library defined to include the two simple Java archive files for the extended components. To see the effect of the substituted components, run theDepartments.jspxpage and try to enter the value of "X" for theLocattribute of any row in theDeptViewview object's results and press (Commit). You'll see the validation error added by the substitutedextendsproject.DeptExcomponent to know that the component substitutions are working.
- This example illustrates how to use the techniques outlined in section 25.10 Substituting Extended Components In a Delivered Applicationof the ADF Developer's Guide for Forms/4GL Developers to substitute extended components into a running application. The
- Array of String Domain Example [10.1.3.1]
- Illustrates binding an array of strings as the value of a view object
WHEREclause bind variable, leveraging the Oracle database'sCAST ASoperator to achieve a variable number of values in a SQLINclause by treating the values in the array as a nested table. Run theCreateTableOfVarcharType.sqlscript before running the example, which features example of using view objects with both the Oracle Positional and Oracle Named bind variable styles. The latter includes a workaround in theEmpViewWithNamedBindingStyleImplclass' overriddencreate()for Bug 5849504, where the view object editor fails to correctly test the syntax of the SQL statement involving an array-valued named bind variable and theTABLEandCAST ASclauses.
- Illustrates binding an array of strings as the value of a view object
- Array of String Domain Example 11g
- Joining Static Array of Database Type Data into View Object Query [11.1.1.0.0] 03-OCT-2008
- This example illustrates an approach to take an array of structured information and bind it into a view object query as one of the tables in order to produce a database join between the static information and the database data. The context in which this example arose was that a service call was returning a list of ranked/scored primary keys, that then needed to be joined with the database table to which the primary keys referred in order to produce a friendly display for end-users that includes more descriptive information about the ranked rows. You'll need to run the
CreateTypes.sqlscript before using the demo to create theSCORED_KEYandSCORED_KEYStypes in the database. TheViewObjectImplWithScoredKeyBindVariableframework extension class centralizes the code required to work with the bind variable of typeoracle.jbo.domain.Array. In this case, its code is binding theSCORED_KEYStype (which is aTABLE OF SCORED_KEY) as an Array ofSCORED_KEYtypes. Both theReadOnlyScoredEmployeesandEntityBasedScoredEmployeesview objects inherit this helper code from this class. ThesetScoredKeysArray()method in the custom view object class of both view objects calls the helper methodnewScoredKeysArray()in the superclass to create the Array of STRUCT and set the value of the view object's bind variable. It expects to receive aListofMapobjects, expecting each Map in the List to contain Map keys "Score" and "Key". The view objects both use the JDBC positional binding style, indicating the (zero-based) integer position of the bind variables as additional metadata in order to still work with the bind variable as a named bind variable in the view object API's. Run theTestClientclass to see the results of joining in the static data with the EMP table.
- This example illustrates an approach to take an array of structured information and bind it into a view object query as one of the tables in order to produce a database join between the static information and the database data. The context in which this example arose was that a service call was returning a list of ranked/scored primary keys, that then needed to be joined with the database table to which the primary keys referred in order to produce a friendly display for end-users that includes more descriptive information about the ranked rows. You'll need to run the
- Using ViewAccessor to Perform Attribute-Level Validation [11.1.1.2] 11-JAN-2010
- This example illustrates two techniques to perform an attribute-level validation based on a view-accessor with a bind variable that needs to be bound to the value that is attempting to be set. For an entity-level validation, you can use a view accessor based list validator for this purpose. However, for the attribute-level use case - since you cannot refer to the
newValueexpression in the view accessor bind variable default Groovy expression - you need to either use a groovy expression validator, a Java method validator, or a custom validation rule. This workspace provides examples of the first and the last of these three options. The Java method validation alternative is left as an exercise to the reader. The Emp EO has two view accessors:CheckDivisibilityBy3based on view object definitiontest.ValidationViewObject, configured to have theVarModulovalue set to 3, andCheckDivisibilityBy7based on the same view object, configured to have the VarModulo value set to 7 The attribute-level Groovy validator on theSalattribute sets the value of theVarValuebind variable on the view accessor, then executes the query. It returns value if the view accessor'sfirst()function returns a non-null result (i.e. at least one row was found). The example also illustrates a more generic approach that doesn't rely on Groovy. I created a new, reusable validation rule calledAttrLevelViewAccessorValidator. I've used an instance of it on theCommattribute, declaratively configuring the validation rule beans two properties:attrNameToBindNewValueTo= "VarValue" andviewAccessorName= "CheckDivisibilityBy7". Run the AM in the tester, and verify that you must enter a Sal value that is divisible by 3 and a Comm value that is divisible by 7. Of course, the example view object would normally be a more interesting query with one or more bind variables going against a table other thanDUAL, but this simple query hopefully will get the basic idea across. If the value being validated were the key attribute of the target view object, you could have used the "Key Exists" validator based on a view accessor instead. This approach is valid when the query you need to validate needs to lookup something that is not the key attribute in the target VO used for validation.
- This example illustrates two techniques to perform an attribute-level validation based on a view-accessor with a bind variable that needs to be bound to the value that is attempting to be set. For an entity-level validation, you can use a view accessor based list validator for this purpose. However, for the attribute-level use case - since you cannot refer to the
- Named Bind Variable Values Based on Attribute in Current Row of Another View Object [10.1.3.2] 17-JUL-2006, Upd: 07-JUN-2007
- This example illustrates a
CustomViewObjectImplframework extension class that adds an interesting feature to any view objects that extend it. It allows such view objects to have named bind variables whose value will be automatically derived from an attribute in the current row of another view object. In the example, theGlobalsview object is a transient view object with no query, one updateable Number attribute namedDepartmentNumber, and a max fetch size set to zero ("No Rows" setting on the "Tuning" panel). TheExampleModuleapplication module overrides the prepareSession() method to insure there is a blank row in the "Globals" view object instance. TheEmployeesview object has a named bind variableTheDeptnothat has a bind-variable-level custom metadata property namedVOAttributeReferenceset to the valueGlobals.DepartmentNumber. Alternatively, the implementation supports setting the view object bind variable to an expression at the view instance level by setting an application module custom property named*ViewInstanceNAme*_*BindVariableName*_VOAttributeReference. This allows you to use the same view object multiple times and have different automatic value expressions for different view object instances. At runtime, theCustomViewObjectImpl's overriddenbindParametersForCollection()method detects any named bind variables with such a custom property set, evaluates the value of the indicated attribute in the current row of the named view object instance, and automatically binds that evaluated value for the bind variable's value. The view object's query has a WHERE clause that accommodates the value of the bind variable bind both NULL or non-NULL. When you run the JSF page, type in a department number and click (Execute) to narrow the list down to only those departments.
- This example illustrates a
- Conditionally Auto-Executing af:query Search Form Based on User Input [11.1.1.2] 31-DEC-2010
- This example illustrates how to conditionally trigger the automatic execution of an
<af:query>component's search when certain conditions are true about the values the user has entered into the search form. Runview1.jspx. After selecting a value forDnameandLocin the search form, the query is automatically executed without the user's having to press the (Search) button. TheView1Beanis the backing bean for theview1.jspxpage in the example. The<af:query>component'squeryOperationListenerproperty is set to an EL expression that "wires" it to fire theonQueryOperationPerformedmethod in the backing bean. The backing bean's event handler code conditionally executes code if the query operation is a criterion update. It accesses the view criteria that is the model-layer object that is bound to the search form and peeks at the values in theDnameandLocview criteria items. If it notices that the user has filled in both criteria items, then it creates a newQueryEventand queue's it up for the same<af:query>component on which the QueryOperationEvent is firing. To ensure that the search form renders theDnameandLocitems in the search form with their autoSubmit property set to true, theautoSubmitUI hint is set to true on bothDnameandLocattributes in theDeptViewview object.
- This example illustrates how to conditionally trigger the automatic execution of an
- 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
DeptViewwhich is an entity-based view object, one namedDeptViewNonEntityBasedwhich is a read-only, non-entity-based view object, and one namedTransientViewObjectthat 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 thebeforeRollback()andafterRollback()method and commenting out the call tosuper. For an entity-based view object, you need to override these two methods as well as call thesetClearCacheOnRollback()method on theoracle.jbo.Transactioninterface, passingfalse. 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 theTransientViewObjectis populated by theprepareSession()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.
- 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
- BeforeCommit Validation Only Once Per Entity Type [10.1.3]
- This example illustrates a technique to introduce a new event called validateEntityCollectionBeforeCommit() that fires only once per entity object type involved in a transaction. The DeptImpl.java class for the Dept entity in the sample illustrates enforcing a rule that only a since department can have the string "XX" in its name. The CustomEntityImpl.java class contains the overridden beforeCommit() method which cooperates with a custom DBTransactionImpl2 subclass to track whether or not the beforeCommit() method has fired yet this commit-cycle for a given entity type. If it's the first entity instance of a given type for which the beforeCommit() is firing, it invokes the new validateEntityCollectionBeforeCommit() method that entities inheriting from this framework extension class can override to code their validation logic.
- Creating a Dynamic Attribute Binding for a Dynamic View Object Attribute
- You can programmatically add dynamic attributes to a ViewObject with the addDynamicAttribute() API. This small sample illustrateshow to create an attributecontrol binding at runtime for your dynamically created View Object attribute. The TestPage illustrates a JSTL-based read-only table, based onhaving dropped a "Read-Only Dynamic Table" from the data control palette. The dynamic table binding figures out its attributes at runtime, so it picks up the"Foo" attribute that is added by the addDynamicAttribute("Foo") call in the DeptViewImpl.java file's create() method. The TestPageAction class in the ViewController project illustrates how to programmatically add an attribute binding for thedynamic "Foo" attribute if it's not already there. The TestPage.jsp uses this binding to allowthe user to enter a value for Foo for anyrow in the Dept table.
- BindingToDynamicViewObject
- Dynamically Binding to Dynamically Created View Object
- Shows a "Tiny SQL*Plus"-like example allowing the user to type in any SQL statement into a web page, and the implementation illustrates how to programmatically construct binding objects in order to render the results from this dynamically created view object.
- Binding SelectBooleanRadio to True/False Value in DB Row [11.1.1.5] 24-NOV-2011
- This example shows how to bind a "T"/"F" value to a data-driven set of selectOneRadio components. Run the
CreateTable.sqlscript to create theDEPT_WITH_BOOLEANtable, then runExample.jspx. When you commit, the "T"/"F" value in theSELECTEDcolumn in the table will reflect the change to the selected radio group button.
- This example shows how to bind a "T"/"F" value to a data-driven set of selectOneRadio components. Run the
- Apply Bind Varible Values to Filter View Link Accessor RowSets [10.1.3.2] 17-APR-07
- This example illustrates a
TestPage.jspxwith a tree binding based on aDepartmentsview object instance of typeDeptView. TheWorksInDeptLinkview link defines a view link accessor attribute namedEmpViewthat is used by the tree binding to access the detail rowsets of employees for each department. TheDeptViewview object defines a custom method namedsetLowHighSalaryRangeForDetailEmployeesAccessorViewObject()that is exposed on the view object's client interface. TheTestPage.jspxincludes 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 theEmpView. TheDeptViewImplclass also contains an overriddencreateViewLinkAccessorRS()method that applies the bind variable values to each view link accessor rowset created. Run theTestPage.jspxpage 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.
- This example illustrates a
- Referencing UserData Map Values from View Object Bind Variables in Groovy [11.1.1.0, SCOTT schema] 27-JAN-2009
- This example includes a
SessionHelperclass to simplify referencing entries in the ADFBC session's userData map from the Groovy expressions providing the default values for bind variables. The user data map is referenced via EL expressions in the two JSPX pages, and it is referenced in Groovy bind variable expressions in two places: (1) at the AM data model level for the VO instance namedAnotherInstanceOfQueryWithBindVarValue(which you can see by selecting the VO instance in the Data Model list and clicking the (Edit) button, and (2) on the view accessor namedQueryWithBindVarValue1of theEmpViewview object. This latter view accessor is used by the LOV definition on theEmpViewview object'sMgrattribute. To try the application, run theSetUserMapValue.jspxpage, typeNameFilterinto thesetUserMapValue_keyfield, and (for example) the letterSinto thesetUserMapValue_valuefield, and click (setUserMapValue). The table in the page updates to show an example of a data model view object instance using the bind variable value from the userData Map. Clicking on the (GoTo Page Referencing Session Value in LOV Bind Var) button takes you to a page where the search form shows that the view accessor's rowset (based on the sameQueryWithBindVarValueview object) is using the bind variable value from the userData map as well. The Groovy expressions that access the userData map use the helper class via the expressiontest.model.SessionHelper.userData(adf.object).NameFilter. A future release of ADF will make it simpler to reference the ADFBC session object without the need for a helper class.
- This example includes a
- Using a CheckBox in an Editable Table with Boolean/Button Binding [11.1.1.1, SCOTT schema] 13-JUL-2009
- This example illustrates how to use the button binding (also known as the boolean binding) in an ADF Table to declaratively handle data entry an attribute whose valid values are one of two choices representing true/false, on/off, yes/no, etc. The
CreateDeptWithFlagTable.sqlcreates a variant of theDEPTtable namedDEPT_WITH_FLAGthat has one additionalFLAGcolumn whose valid values are "Y" or "N". TheDeptWithFlagEO indicates a UI hint on itsFlagattribute to indicate that it prefers to render as a "Checkbox". Dragging and dropping theDeptWithFlagView1data collection from the data control palette as an "ADF Table", JDeveloper infers the correctselectBooleanCheckboxcontrol for theFlagattribute. However, there is two additional (simple) steps required to make it work correctly in a table. First, using the overview editor for the pageDefinition, I created a new button binding named "Flag" for theFlagattribute, indicating the values of "Y" for selected and "N" for unselected. With theview1PageDefpage definition as the active editor, I expanded theDeptWithFlagView1tree binding, its nodeDefinition folder, and the AttrNames folder inside it to select theFlagattribute of the tree binding node definition. Then, using the Property Inspector, I set the value of theBindsproperty of thisFlagattribute name element to "Flag" (without quotes), which references the name of the button binding created above.
- This example illustrates how to use the button binding (also known as the boolean binding) in an ADF Table to declaratively handle data entry an attribute whose valid values are one of two choices representing true/false, on/off, yes/no, etc. The
- 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.sqlscript to create the PL/SQL package namedexample_pkgused by the demo. This package contains a single proceduredo_somethingwhich accepts a string parameter, number parameter, and date parameter and inserts these values into a new row in theEXAMPLE_PKG_TABLEtable. In the J2EE application, the stored procedure invocation is encapsulated inside the business service inside the custom application module methodcollectDataUsingStoredProcedure. 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 theViewControllerproject was created by dragging thecollectDataUsingStoredProcedurefrom 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 namedExamplePkgTablefrom 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.
- The example illustrates how to create a JSF parameter form for calling a PL/SQL stored procedure. You'll need to run the supplied
- Call Stored Procedure From a DataAction or JClient Button
- Shows the best practice technique for invoking a database stored procedure encapsulated behind a custom
ApplicationModulemethod. Includes examples for invoking it both from an ADFDataAction(in the ViewController project) as well as a JClient button event handler method (in the SwingClient project).
- Shows the best practice technique for invoking a database stored procedure encapsulated behind a custom
- Reference View Object and View Row Methods from Groovy [11.1.1.1, SCOTT schema] 03-SEP-2009
- The
EmpViewview object in this example features two transient, Groovy calculated attributes. The attribute namedValueUsingVOFunctionreferences a custommyFunctionAtVOLevel()method on theEmpViewImplclass, while the attribute namedValueUsingVORowFunctionreferences a custommyFunctionAtVORowLevel()method on theEmpViewRowImplclass, in both cases passing in the value of theSalattribute. The methods simply return the value passed in surrounded by either parenthesis or square brackets.
- The
- Implementing Custom View Row Hint Behavior [11.1.1.0.0] 9-DEC-2008
- This example illustrates how to provide a custom view row attribute hints implementation. The
EmpViewRowclass overrides thecreateViewRowAttrHintsmethod to return a new instance of theEmpViewRowAttributeHintsImplclass (which extends the framework base classViewRowAttrHints. In theEmpViewRowAttributeHintsImplclass, notice that we've overridden thegetHint()API to conditionally return a value for user-defined attribute hints named "mindate" and "maxdate". These hints are coded to look at the value of theHiredatein the current row, and return a date String that represents three days before that date for "mindate" and three days after that date for "maxdate". The class also overrides thegetLabelAPI to customize the value of the "label" UI hint for the Job attribute. Run theTestPage.jspxand try to edit a "Hiredate" value. You'll see that the date picker only allows you to change the date to a date that is within a span of three days before to three days after the current value. This occurs due to the UI component's referencing the custom "mindate" and "maxdate" hints appropriately. Also, you'll notice that the label for the "Job" field is the default label with the value of theSalattribute appended to it.
- This example illustrates how to provide a custom view row attribute hints implementation. The
- Change Preferred UI Locale with a Button in the Page [10.1.3.4] 2006, Upd: 11-NOV-2008
- 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
CustomFacesPageLifecycleclass is a custom ADF Faces page lifecycle class that overrides theprepareRenderphase 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 theAppmanaged bean to see what the user's preferred locale is. In the overriddenprepareRendermethod, ifApp.preferredLocaleis different from the current UI View Root's locale, then the method sets the locale of the view to the preferred locale before callingsuper.prepareRender. If it ends up changing the locale, it also forces any List Binding objects with a translatable label for their null entry (like "") 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 theApp.preferredLocaleto eitherENGLISHorITALIANdepending 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, theAnotherPage.jspxpage allows the user to change the value of a transient number attribute that was added to the entity object. The format mask of#0.00is specified as part of the UI control hints at the entity object level and you can see that when in Italian a number like3.45is presented and edited using the locale-appropriate decimal symbol3,45. The regular JSP pageRegularJSPPageNotUsingJSF.jspxin 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.
- 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
- 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.sqlscript in theModelproject to create aSETTINGStable 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, theSTATUScolumn in theSETTINGStable is defined asNUMBER(1)with0representing false and1representing true. The example illustrates how you can introduce a transientBoolean-valued attributeStatusAsBooleanto work with the numerical true/false value as a Boolean. In the customSettingsViewRowImplrow class, thegetStatusAsBooleanandsetStatusAsBooleanmethods have been written to convert the numerical value to a boolean upon reading it and convert a boolean value to the correctNumbervalue upon writing it. In the JSPX page in theViewControllerproject, theaf:selectBooleanCheckboxis bound declaratively to theStatusAsBooleanattribute 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 as0or1appropriately.
- 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
- Test Consistency of an Entity Without Locking or Modifying Cache Data [10.1.3]
- A customer asked how he could test whether an unmodified entity instance is consistent or not with the corresponding row in the database without having to first modify/lock the row and without updating the entity cache with the new values. These particular requirements meant that he couldn't use the built-in features that perform this comparison for you. This example illustrates a possible generic solution to this by constructing an on-the-fly, read-only view object to fetch the values of the persistent attributes in the entity and comparing their values with the current entity attributes. See the
testConsistencymethod in theCustomEntityImplclass. Run the sample Form.java class and click on the (testConsistencyOfCurrentRow) button to try it out. ThetextConsistencyOfCurrentRow()method is a custom method the view object's custom interface which gets the current row, then delegates to it'stestConsistency()method mentioned above. NOTE: this solution could be optimized by comparing only a "change indicator" column in the entity if it is marked and it also doesn't do any special treatment for LOB attributes whose comparisons you generally want to avoid due to their overhead.
- A customer asked how he could test whether an unmodified entity instance is consistent or not with the corresponding row in the database without having to first modify/lock the row and without updating the entity cache with the new values. These particular requirements meant that he couldn't use the built-in features that perform this comparison for you. This example illustrates a possible generic solution to this by constructing an on-the-fly, read-only view object to fetch the values of the persistent attributes in the entity and comparing their values with the current entity attributes. See the
- Using JSTL to Refer to Value of Field in Following Row for Conditional Formatting
- This example contains a single TestPage.jsp that shows a pageable table of EMP table rows. It illustrates how to use the varStatus attribute of the <c:forEach> tag to refer to the loop index, and then use this as an array offset into the array of rows in the current range to make a comparison between the current row's Deptno value and the Deptno value of the next row. In this case, if the values are different, it formats the cells of the HTML table to have a CSS border along their bottom edge to create a visual separation on the page.
- Programmatically Manipulating a Table's QBE Filter Fields [11.1.1.1, SCOTT schema] 14-AUG-2009
- This example illustrates how to programmatically clear the
af:tablecomponent's filter fields. Thetest.jspxpage'saf:tablecomponent has itsbindingproperty set to expose the UI component in theTestPagebacking bean as a property namedtable. TheTestPagebean has four button event handler methods that are referenced by the four different buttons on the page. One clears all table search fields, one clears only theDnamesearch field, the third method clears all the search fields and also queues an event to reexecute the table's query, and the fourth one programmatically populates selected search filter fields and reexecutes the table's query. The backing bean contains helper methods that illustrate how to access the table component's FilterableQueryDescriptor and the "Filter Criteria"Mapit contains. Clearing selected entries from this filter criteria map clears the corresponding search field in the UI. While not required to implement the search field manipulation, the example also illustrates how you can override the default QueryListener method to call customonTableQueryExecutedquery handler method which can include code before or after its invocation of the built-in query listener event handler method provided by the search binding object.
- This example illustrates how to programmatically clear the
- Conditionally Refreshing Associated Entities via Accessors, Driven by Component Metadata
- This sample illustrates some generic framework extension code to customize how the Entity object works so that associated entities can be conditionally refreshed from the database. By default, accessingassociated entities using entity accessor attributes will fetch the entity into the entity cache if not there already, but subsequently use the cache to satisfy the attribute access. This technique illustrate how you can use custom entity object metadata properties to annotate particular entity object accessor attributes where you want to eagerly refresh the value of the associated entity (or entity rowset, in the case of a 1-to-many association) whenever its accessed. A key design principal of the ADF Business Components layer of Oracle ADF is that it uses the database as its shared cache between different user's work. Each root application module instance has its own related transaction where local data is read and cached before any changes get committed, but within the span of a single transaction if user 1 has read and cached an entity object while simultaneously user 2 has read, updated, and committed a change to that same entity, user 1 will continue to "see" the object as it is in his cache. Selectively performing this eager refreshing of certain key entities can insure that business logic written using entity accessor attributes will always see the latest changes made by any user session during its current transaction. Notice the overridden getAttributeInternal() method in the MyEntityImpl class, and the custom metadta properties on the Dept and Emp entities in the sample. Launch two separate Business Components tester instance to simulate two parallel user transactions, and try updating the value of a Dept.Dname to "XXX" in one tester and committing it, then seeing that the Emp-level business rule fails validation. Conversely, try updating an Emp.Ename to "XXX" in one tester instance and committing it, then seeing that the Dept-level business rule values validation.
- Console Program Example of Using ADF Data Binding Layer
- This simple TestClient.java program illustrates how to use the ADF data binding layer from a simple Java console program. It shows working through the same API's with both a JavaBean-based data control and an ADF ApplicationModule data control. NOTE: If you try to open this project in JDeveloper 10.1.3, you will need to double-click on the
TestClientUIModel.xmlfile to open it in the code editor before it will get migrated to the 10.1.3 format correctly.
- This simple TestClient.java program illustrates how to use the ADF data binding layer from a simple Java console program. It shows working through the same API's with both a JavaBean-based data control and an ADF ApplicationModule data control. NOTE: If you try to open this project in JDeveloper 10.1.3, you will need to double-click on the
- ControlBreakTable
- Customizing Application Error Handler to Support Informational Messages [11.1.1.0, SCOTT schema] 20-MAR-2009
- The base ADF product only distinguishes between warnings and errors, so there is no default way to get a JSF message with severity of
INFO. This example includes aCustomErrorHandlerclass that implements handling for informational messages. TheaddInformationMessageTest()method in theAppModulecustom java class adds an informational message by using theaddWarning()API, passing a custom subtype ofJboWarningcalledInformationalMessage. Due to the way warnings are wrapped before they are passed to the custom error handler'sgetDisplayMessage()method by the ADF framework, theInformationalMessageconstructor sets a value into the error parameters that theCustomErrorHandleruses to recognize the warning subtype as an informational message. The overriddengetDisplayMessage()method in the error handler class detects whether the exception is an informational warning, and if it is, it adds an informational message to the FacesContext. It uses thesetProperty()andgetProperty()API of the JboWarning object to set a flag it can use to detect whether the exception has already been reported by this custom mechanism. This is required because ADF will invoke the getDisplayMessage() two times for each exception reported, later only one of which gets reported to the user. Run thePage.jspxto try the example. To see an error be reported, enter a salary of 5002 and click (Next). To try a warning, enter a salary of 5001 and click (Next). To see an informational message, click the (addInformationMessageTest) button. Notice that the custom error handler class is declaratively configured via theErrorClassattribute on the root element of theDataBindings.cpxfile (which shows as theErrorClassproperty of the root element in the Property Inspector.
- The base ADF product only distinguishes between warnings and errors, so there is no default way to get a JSF message with severity of
- Custom Domain to Persist Transient ArrayList of Account Beans [10.1.3.2] 03-APR-07
- This example shows a custom
ListOfAccountsdomain that implements the necessary interfaces to allow its contents - a list ofAccountbeans - to be passivated and activated correctly to the application module persistent state snapshot. It shows a combination of required aspects including implementing theXMLDomainWriterandDomainInterfaceinterfaces, as well as containing apublic static getXMLDomainFactory()method that returns an instance of a class that implements theXMLDomainReaderFactoryandXMLDomainFactoryinterfaces. TheExampleTransientViewin the project is a transient view object with oneString-valued attribute marked as the key attribute, and anotherListOfAccountsattribute of typemodel.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'screate()method contains the best practice code required for a transient view object that will be programmatically populated by creating and inserting rows. Run theTestClientclass 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.
- This example shows a custom
- Example of Using Customized ADF Binding Class in a ADF/Struts Web Application
- This example illustrates the minimal details necessary to get the ADF binding layer to use a customized ADF binding implementation class at runtime, in the context of a web application. The steps would be the same for an ADF JClient application or other use case, the only thing that might change is the place you register you custom binding definition factory with the JUMetaObjectManager. In the example, the MyADFBindingFilter extends the base ADFBindingFilter and calls JUMetaObjectManager.setControlDefFactory() to register a custom control binding definition factory. MyCustomBindingDefFactoryImpl extends the default JUBindingDefFactoryImpl and overrides the createControlDef() method to return a different binding definition class for one of the subtypes of bindings. In this case, I've chosen to provide a customized binding class the the binding subtype "DCTextField". MyCtrlAttrsDef extends the default JUCtrlAttrsDef and overrides the createControlBindingInstance() method to return a new instance of my customized MyCtrlAttrsBinding instead of the default. And finally, that MyCtrlAttrsBinding extends the default JUCtrlAttrsBinding object and overrides the setInputValue() method to print out a custom message to system output to allow you to see at runtime that the custom binding is getting used.
- CustomBeanDCDefinition
- Running Custom Backing Bean Code Before/After Default Table Selection Listener [10.1.3.2] 16-AUG-07
- This example illustrates a
TestPage.jspxpage with anaf:tablecomponent whoseselectionListenerproperty has been modified from the default EL expression dropped when the table was created, to instead call a selection listener method namedonTableSelectionChanged()in theTestPagebacking bean. This default EL expression normally looks like#{bindings.*TableBindingName*.collectionModel.makeCurrent}which declaratively "wires" the table selection event to invoke themakeCurrent()method on theCollectionModelof the table binding. In order to preseve the default data binding functionality that reacts to the table selection change, this backing bean method uses theinvokeMethod()helper method of theELhelper class to call the default functionality with custom code before and after it. The EL helper class is in theFwkExtensionsproject, which is marked as a project-level dependency.
- This example illustrates a
- Introducing a Checkbox to Toggle a Custom SQL Predicate on an LOV's Search Form. [11.1.1.0.0] 19-NOV-2008
- This example shows a technique to include a checkbox in a declaratively-defined LOV's search form which toggles on or off a custom SQL fragment's being applied to the search. In this simple example, we use the checkbox to allow the user to limit the LOV search results to only include departments whose id is a multiple of 20 (or not). The ViewController project includes a simple
view1.jspxpage with a default ADF Form dropped for the EmpView. TheDeptnoattribute of theEmpViewdefines an LOV that references a view accessor based onDeptView. TheDeptViewview object has an additional SQL-calculated attribute namedExtraAttrof typeBoolean. The SQL expression for the attribute is just the quoted string 'FALSE'. There is a view criteria namedLOVSearchCriteriadefined onDeptViewand it includes view criteria items forDname,Loc, andExtraAttr. TheExtraAttrhas the following UI hints defined: Label Text is set to 'Show Only Multiples of 20?'; Tooltip Text is set to some helpful text, and Control Type is set to 'Checkbox'. TheDeptViewview object uses theCustomViewObjectImplclass as its base framework class, and so theDeptViewImplcustom view object class extends thatCustomViewObjectImplto inherit a few helper methods. The baseCustomViewObjectImploverrides thegetCriteriaItemClause()framework API invoke two other methodsgetCriteriaItemClauseForDatabaseUse()andgetCriteriaItemClauseForCache()to customize the SQL fragment returned for a particular view criteria item. TheDeptViewImplclass overrides these two methods so that if the view criteria is "LOVSearchCriteria" and the view criteria item is "ExtraAttr" and beging asked for the fragment to use for database filtering, then we return the SQL fragment "MOD(DEPTNO,20)=0" if the value of the view criteria item is Boolean.TRUE, otherwise we return the harmless "1=1" predicate. For the in-memory cache fragment, we override the other method and return "1=1". Run the form, click the dropdown list on the combobox and click on the "Search..." link to access the popup LOV dialog. You'll see that if you check the checkbox, then only departments whose id's are multiples of 20 appear in the list, otherwise they are not restricted by this additional (custom) criteria.
- This example shows a technique to include a checkbox in a declaratively-defined LOV's search form which toggles on or off a custom SQL fragment's being applied to the search. In this simple example, we use the checkbox to allow the user to limit the LOV search results to only include departments whose id is a multiple of 20 (or not). The ViewController project includes a simple
- 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 JHeadstartteam). The
CustomFacesPageLifecycleclass is registered in thefaces-config.xmlfile as an application-scoped managed bean namedPageLifecycle(the name is arbitrary, of course). TheCustomADFPhaseListenerclass is registered in the "Life Cycle" section of thefaces-config.xmlas well. Its overriddencreatePageLifecycle()method uses theELhelper class to return the custom page lifecycle class using the methodEL.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 itsActionproperty 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 theDnameaf:inputText fields whoseValueproperty 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 customizedMapapproach to effectively provide simple, one-argument callable methods. In this case, thegetAttributeBindingWrappermap wraps theAttributeBindingpassed in as an argument. The second of the twoDnameinputText's shows that by wrapping the attribute binding in this way and setting theDisabledproperty 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.
- This example illustrates an interesting technique (that I initially learned from the always-clever JHeadstartteam). The
- Set Fixed JDBC URL Connection to Custom Value from Alternative Source
- This example is a twist on the DynamicCredentials example above, simplified to contain only the essential ingredients to provide the JDBC URL connection information (username, password, JDBC URL) from an alternative source than the information in the bc4j.xcfg file. The example hard-codes the information inside the CustomJDBCURLInfoProvider class. You could modify this example to read the information from some alternative source like a properties file, system parameters, or other location to meet your needs.
- Customizing How ADF BC Metadata Gets Loaded
- This example shows an example of how to implement a custom XMLContext implementation and use it at runtime. In the example project, the MyMetaobjectContext class extends the base XMLContextImpl class in the ADF BC framework, and overrides the lookup() method. This method is responsible for returning an InputStream over an XML document containing valid metdata for the ADF BC component whose fully-qualified name is passed in. My custom implementation loads the XML from an alternative source if the component being looked up is "test.Dept", otherwise it performs the default lookup (which will find the XML metadata in a file on disk in the appropriate directory matching the fully-qualified component's package name). Set a breakpoint in the lookup() method of MyMetaobjectContext class, then debug the TestModuleImpl class to launch the TestModule application module in the Business Components tester in debug mode. We indicate to the framework that it should use our customized metadata context class by setting the configurationi property MetaObjectContext to the fully-qualified class name of the XMLContext implementation that we want to use. If you look at the properties in the TestModuleLocal configuration for the TestModule application module, you'll see that property there, set to the value test.MyMetaobjectContext.
- DataPushDynamicGraphs
- DataPushSampleFilter
- Custom DateRange Validation Rule Bean with Custom Design Time Editor
- Did you know that you can extend the set of built-in, declarative validation rules by writing your own? Sure you can! This example project illustrates an example DateRangeRule validator bean that validates that a starting date attributes comes before an ending date attribute. It also illustrates how you can define a custom JavaBean Customizer panel to provide a custom editing experience for downstream users of your validator bean in the ADF Business Components design time. The DateRangeRule validator bean is linked to its custom DateRangeRuleCustomizer via the DateRangeRuleBeanInfo class. This is a standard JavaBeans programming technique. The project contains two deployment profiles: one produces a runtime JAR file with only the DateRangeRule, the other produces a design time JAR file with the BeanInfo and the Customizer for the rule. To use the date validation rule in any Business Components project, just add a library for these two JAR files, then visit the "Registered Rules" panel under the "Business Components" section of the project properties to (Add...) this test.rules.DateRangeRule as one of the rules you want to use, andgive it the name "DateRange"Once you've done that, the DateRange validator will appear in the list for you to add to your entity objects on the "Validation" panel of the Entity Object editor. The custom editor panel allows you to pick the Start Date Attribute and the End Date Attribute from the list of date-type attributes in your entity object.
- JDev 9.0.3/9.0.4 BC4J/JSP Request Processor to Show Error Page for Down Database
- This sample is a JDeveloper 9.0.4.1 project with a simple JSP using the BC4J jbo:* tag library to show department information. It contains a custom Struts request processor class, test.MyRequestProcessor, which extends the BC4JRequestProcessor used in 9.0.3 and 9.0.4 BC4J/Struts applications to properly handle the case when the database is down, so that a declaratively-configured struts global exception mapping can forward control to a "DatabaseIsDown.jsp" page. It relies on a custom subclass of the BC4JRequestProcessor to catch the ApplicationPoolException raised earlier in the Struts request processor lifecycle, and then later in the lifecycle throw the exception as part of the processActionPerform() step, so that Struts' declarative exception handling will work as expected.
- 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 simpleCustomEntityImplframework extension class on which both theDeptandEmpentities in the sample are based. It's overriddencreate()method tests for the presence of a custom attribute-level metadata property namedSequenceNameand if detected, populates the attribute's default value from the next number in that sequence using the same basic code as above. TheDeptentity defines the customSequenceNameproperty on itsDeptnoattribute with the valueDEPT_TABLE_SEQ, while theEmpentity defines that custom property on itsEmpnoattribute with the valueEMP_TABLE_SEQ. The suppliedCreateDeptAndEmpTables.sqlscript creates the tables and sequences for you.
- 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
- Automatic Runtime Query/Join Pruning with Declarative View Objects [11.1.1.0, HR schema] 20-DEC-2008
- This example contains a single
EmployeeAllInfoview whose SQL mode is set to use the new-in-11g setting of 'Declarative'. It contains one editableEmployeesentity usage, and six additional reference entity usages showing related information about the employee's department, the department's manager, the department's location, the department's region, the employee's job, and the department's country. When a view object is in declarative mode, its SQL statement is determined at runtime instead of at design time. Attributes in the view object can have their Selected in Query property set to false, and these attributes will only be selected if they are referenced by the page definition for the current page, otherwise they will be left out of the query. When multiple entity usages are involved, if all the attributes from a given entity usage are left out of the query, then the ADFBC runtime "prunes" that table related to that entity usage out of the query and does not perform that join. The application module in theModelproject includes three different instances of the sameEmployeeAllInfoview object. You can observe the different runtime queries performed by the three different JSPX pages by looking in the log while performing a search in each page. The fileQueries.txtincluded in theViewControllerproject contains a formatted version of the different queries. You can see in the query for theMinimalEmployeeInfo.jspxpage, that only theEMPLOYEEStable is included. In the query forMediumEmployeeInfo.jspxyou seeEMPLOYEES,DEPARTMENTS,EMPLOYEES(a second time for the manager), andJOBS. The query for the final page joins all of the tables.
- This example contains a single
- Conditional View/Controller-Layer Defaulting of Fields in a Create Form [10.1.3]
- Generally we advise putting business logic like attribute default values into on overridden create() method of your Entity Object as described in section 9.4.1 "Defaulting Values for New Rows at Create Time" of the ADF Developer's Guide for Forms/4GL Developers. Section 9.10, "How to Store Information About the Current User Session"explains how a custom application module method can save data into the per-user session "user data" hashtable, which entity object business logic like create()-time defaulting can then reference. However this example contains a Create.jspx page with a Create.java backing bean that illustrates a case of controller-layer logic that conditionally returns a default value for the "Loc" binding based on controller-layer flags like the presence of a
#{requestScope.creating}attribute, and on the value of a#{sessionScope.locDefaultValue}attribute. The#{requestScope.creating}flag is set declaratively using an<af:setActionListener>on the (Create) button in the Browse.jspx page. The example works by using a backing bean property to "decorate" the normal Loc attribute binding. If certain conditions are true, then thegetLoc()method in the backing bean returns the value of the session variable instead of returning the normal value of the Loc binding. Try setting the session value to some value, then experiment with clicking on the different buttons in the browse page to show the defaulting occurring or not occurring as inidicated on the button labels. We adopt this approach instead of trying to programmatically set the binding immediately to the conditional controller-layer default value so that we don't cause the new row to change from its initialized status to a "new" status (which will add it to the rowset. See section 10.4.4 What You May Need to Know About Create and CreateInsert in the developer's guide for more information on this.
- Generally we advise putting business logic like attribute default values into on overridden create() method of your Entity Object as described in section 9.4.1 "Defaulting Values for New Rows at Create Time" of the ADF Developer's Guide for Forms/4GL Developers. Section 9.10, "How to Store Information About the Current User Session"explains how a custom application module method can save data into the per-user session "user data" hashtable, which entity object business logic like create()-time defaulting can then reference. However this example contains a Create.jspx page with a Create.java backing bean that illustrates a case of controller-layer logic that conditionally returns a default value for the "Loc" binding based on controller-layer flags like the presence of a
- DeleteEmpWithConfirm
- Deleting an Employee with Confirmation in a Web Application
- It uses just two data pages and leverages the built-in event-handling features of ADF described in the ADF Data Binding Primer and ADF/Struts Overview. The pages use the post-back pattern to handle their own events before forwarding. You also might want to look at the web log article I wrote on different techniques for invoking multiple actions (as it happens, related to Delete, but not specific to Delete). Things to notice about the example: The "confirmDelete" action binding in the employeeList page's binding container is mapped to the setCurrentRowWithKey action so that it automatically fires when the "confirmDelete" event is triggered. The "confirmDelete" forward is then automatically selected to navigate to the confirmation page. If you click the "Confirm Delete" link on the confirmation page, then the onConfirmDelete method in the EmployeeDeleteConfirmAction class fires, and then it executes the delete, followed by a commit.
- Deleting Multiple Employees Based on Selected Checkboxes
- This exampleshows how to write a JSP page that proposes a checkbox next to every employees name, and allows the user to tick any number of checkboxes to delete all of those employees when the (Delete) button is pressed. Key logic happens in the application module method deleteMultipleEmpsByEmpno() which accepts a String[] parameter of Empnos so we can directly pass theString[]of selected checkbox Empno values from the web container to the application module method. The data action event handler onDeleteMultiple in the DeleteMultipleEmpsAction class invokes the custom AM method.
- Using the queryPerformed Property of the Search Binding to Show a 'No Records Found' Message [11.1.1.0.0] 09-NOV-2008
- The EL expressions used in the
renderedproperty of several components in theFindDepartments.jspxpage in this example use thequeryPerformedproperty of the search binding to conditionally hide the results table until the user has performed a query. In addition, the same property is used to conditionally show an 'Enter some criteria...' message or a 'No departments found' message as appropriate. For more information about the declarative options the search binding supports, see the section entitled 'Changes to search form binding default behavior since Technology Preview 4' in the JDeveloper 11g release notes.
- The EL expressions used in the
- 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 theirimmediateproperty to the valuetruewhich causes validation to be circumvented. There are two functionally-identical JSPX pages, one which programmatically callsresetValue()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.
- This example contains a
- DRM004_AutoReduceSearch
- DRM005_CSSAnimations
- DRM007_RevealPanel
- DRM008_InputSliderMeasureSelector
- DRM009_ConveyorTabs
- DRM010_UKOUGMobile
- DRM011_MessagePrioritization
- DRM012_DeploymentPlan
- Dropdown Lists in Table with Different Choices per Row [10.1.3, HR schema]
- Complementing screencast #7 ("Creating an Editable Table with a Dropdown List in Each Row"), this example illustrates how to implement the more complex scenario where the list of valid choices for the dropdown list in each row is a function of some value in the row. Specifically here, the table of "Departments" shows a dropdown list for each department row where the list of choices is the set of employees in that same department. The example allows the user to choose between using a read-only view object or an entity-based view object to drive the list. While in practice you wouldn't provide your own end users this choice, the sample helps you understand whether you should choose an entity-based view object or read-only view object for your own LOV queries. Instead of performing a separate query for each department to retrieve the employees in that department, the example illustrates querying all of the employees and then changing the 'QueryMode' in order to perform in-memory filtering as needed to return only those employees that below to a particular department. See section 27.5 "Performing In-Memory Sorting and Filtering of Row Sets" in the ADF Developer's Guide for Forms/4GL Developers for more information on in-memory filtering. The JSF backing bean for the page uses a useful trick to allow invoking an application module method with a single parameter from inside an EL expression. You'll see such an expression in the JSPX page in the sample by looking at the
<f:selectItems>tag that's generating the set of choices for the selectOneChoice dropdown list in each row of the table. Itsvalueattribute is set to the EL expression#{DropdownListInTableChangingByRow.lovList[row.DepartmentId]}. This syntax accesses a backing bean property namedlovListand if that property is aMap, then the EL resolver will call theget()method on theMap-valued property to access the entry with the key equal to the expressionrow.DepartmentIdinside the square brackets. By implementing thelovListproperty in the backing bean as an anonymous subclass ofjava.util.HashMapwith an ovverriddenget(Object key)method, we can intercept the attempt to access the Map entry with the key of the current row's department id, and instead have its value come from an invocation to an application module method that returns the correct set of employee choices for that current department. Not a totally obviously technique, but I've included further comments in the code that explain more of the implementation details.
- Complementing screencast #7 ("Creating an Editable Table with a Dropdown List in Each Row"), this example illustrates how to implement the more complex scenario where the list of valid choices for the dropdown list in each row is a function of some value in the row. Specifically here, the table of "Departments" shows a dropdown list for each department row where the list of choices is the set of employees in that same department. The example allows the user to choose between using a read-only view object or an entity-based view object to drive the list. While in practice you wouldn't provide your own end users this choice, the sample helps you understand whether you should choose an entity-based view object or read-only view object for your own LOV queries. Instead of performing a separate query for each department to retrieve the employees in that department, the example illustrates querying all of the employees and then changing the 'QueryMode' in order to perform in-memory filtering as needed to return only those employees that below to a particular department. See section 27.5 "Performing In-Memory Sorting and Filtering of Row Sets" in the ADF Developer's Guide for Forms/4GL Developers for more information on in-memory filtering. The JSF backing bean for the page uses a useful trick to allow invoking an application module method with a single parameter from inside an EL expression. You'll see such an expression in the JSPX page in the sample by looking at the
- 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
DumpPoolStatisticsServletis configured in theweb.xmlto map to the URL/DumpPoolStatistics. TheDumpConnectionPoolStatisticsServletis configured in theweb.xmlto 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 theEditEmps.jspxand 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 theDumpConnectionPoolStatisticsservlet with care in a production environment and not leaving the configured permanently (unless you protect access to it with a password using HTTP authentication).
- This example illustrates a servlet that dumps application module pooling statistics and/or ADFBC database connection pooling statistics to the browser. The
- Dynamic JDBC Credentials for Model 1 and Model 2 [10.1.3.3] 2006, Upd: 17-MAY-2007
- After reading the OTN article How To Support Dynamic JDBC Credentials, several customers asked whether the same techniques will work outside of a Struts context. The ADF related code to support dynamic credentials is not dependent on Struts, but a tiny bit of the example code referenced a "main.do" in a place that made it only work for Struts. This example app illustrates the technique can work with both Model 1 or Model 2, including both JSP/Struts and JSF. The web.xml file for each ViewController project contains a context parameter that define the login page to redirect to for that particular web application. The JSF project contains a second context parameter
FacesURLPatternas well. Due to Bug# 5080057, setting thejbo.ampool.sessioncookiefactoryclassproperty in the configuration is not correctly saved to thebc4j.xcfgfile. So, in order to configure a custom session cookie factory class as required to repurpose the code in this example in your own projects, you'll need to hand-edit thebc4j.xcfgfile to insert the child element<jbo.ampool.sessioncookiefactoryclass>test.DynamicJDBCSessionCookieFactory</jbo.ampool.sessioncookiefactoryclass>inside the appropriate<AppModuleConfig>element for the configuration in question. (NOTE: The version of this workspace that works for JDeveloper 9.0.5 and 10.1.2 is still available here).
- After reading the OTN article How To Support Dynamic JDBC Credentials, several customers asked whether the same techniques will work outside of a Struts context. The ADF related code to support dynamic credentials is not dependent on Struts, but a tiny bit of the example code referenced a "main.do" in a place that made it only work for Struts. This example app illustrates the technique can work with both Model 1 or Model 2, including both JSP/Struts and JSF. The web.xml file for each ViewController project contains a context parameter that define the login page to redirect to for that particular web application. The JSF project contains a second context parameter
- Dynamic, Data-Driven JSF Parameter Form [10.1.3]
- This example illustrates one technique for implementing a dynamic, data-driven parameter form. The
Databaseproject in the workspace containsCreateTables.sqlandInsertData.sqlscripts that define and populate four simple tables:PARAMETER_FORM_DEFINITION,PARAMETER_DEFINITION,PARAMETER_CHOICES, andPARAMETER_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. TheParameterFormItemsview 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 theParameterFormItemsview object and theParameterChoicesViewthat enables a view link accessor attribute namedParameterChoicesin each row of theParameterFormItemsview object's results. In theViewControllerproject, you will find three pages. TheTestParameterForm.jspxpage 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 theDynamicParameterForm.jspxpage. That page is the real meat of the example. It includes a ADFM tree binding to expose the hierarchical collection of data for theParameterFormItemsand its collection of available choices (via theParameterChoicesview link accessor attribute). The page definition for this page includes aninvokeActionthat triggers the firing of anExecuteWithParamsaction binding when the page is not handling a post-back (RefreshCondition="#{adfFacesContext.postback==false}"). This allows theParameterFormItemsview object'sTheFormIdnamed 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 theDisplayTypeattribute of the parameter definition. The switcher determines whether to display the item as aninputText, aselectOneChoice(i.e. dropdown list), or aselectOneRadio(i.e. radio group) depending on whether theDisplayTypeof 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 namedUserValuethat has been added to theParameterFormValuesview object. TheShowUserEnteredValues.jspxpage renders the parameters along with the user-entered values, and theDynamicParameterForm.javabacking 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 theParameterFormModuleto maintain the parameter form metadata that drives the parameter forms, adding a new form, new items, or new item choices as needed.
- This example illustrates one technique for implementing a dynamic, data-driven parameter form. The
- Cascading Lists in JSF [10.1.3.2, HR schema] 2006, Upd: 18-JUN-2007
- This sample works on the HR schema, but requires first running the supplied
CreateAndPopulateCitiesTable.sqlscript to create and populate an additionalCITIEStable that it uses. The sample includes two JSF pages, illustrating two different styles of cascading poplists you might need to implement. Use the first style, represented by theCascadingLists.jsppage, when the driving list serves only to partition the set of choices in the dependent list. In that page, only theCountryIdis actually an attribute of theLocationsViewrow. TheRegionIdof the selected region is not present. On the other hand, use the second style, represented by theCascadingListsUsingTwoListBindings.jspxwhen both the driving list and the dependent list have to update the value of an attribute in the row being edited. In that page, a row in theCitiesViewincludes both aRegionIdand aCountryIdattribute. TheCascadingLists.jsppage allows creating, updating, and deleting locations. The page has a "Regions" dropdown list and a "Countries" dropdown list. The RegionsselectOneChoiceis bound using a navigation list binding, and the Countries selectOneChoice is bound using a normal (LOV-style) list binding. TheonRegionListChangedbacking bean method fires for theValueChangedEventof the Regions dropdown, and simply sets a request-scoped attribute to signal that the user has changed the regions choice. This is a sign they want to be editing the the current row to be a country in a different region. TheinvokeActionin the page definition invokes an application module method during the renderModel phase (Refresh="renderModel") if the request-scoped property just mentioned is not set. TheonCountryChangedbacking bean method fires for theValueChangeEventof the Countries dropdown, setting a different request-scoped attribute to signal that the user has changed the country choice. Since the navigation list causes the current row in theRegionsIteratorto change based on the user's current selection, and since theCountriesview instance in the data model is an actively-coordinated detail view based on theRegionsmaster view, the changing of the current row in theRegionsview automatically coordinates theCountriesview to have the correlated set of countries for the new current region. TheCascadingListsUsingTwoListBindings.jspxpage uses two list bindings instead of having the driving this be based on a navigation list. TheRegionIdlist gets its set of valid choices from theRegionsListin the data model. TheCountryIdgets its set of valid choices from theCountriesListForRegionview instance in the data model. This latter view instance is based on theCountriesListForRegionview defintion that uses a named bind variable (TheRegionId) in order to filter the list of countries by a region id supplied as a parameter. The lists useValueChangeListenermethods like the ones used in the other page. The difference in this example is what therefreshCountryListUnlessCountryChanginginvokeAction invokeAction executable in the page def is doing. In this page's page definition, this invokeAction causes anExecuteWithParamsaction binding on theCountriesListForRegionIteratorto be triggered during theprepareRenderlifecycle phase whenever the user is not changing the country. Notice that this invokeAction is sequenced after the iterator binding forCitiesViewIteratorso that the value of the RegionId binding will reflect the up-to-date state of the currentCitiesViewrow. ThatExecuteWithParamsaction binding is configured to pass the value of the#{bindings.RegionId.inputValue}as the value of theTheRegionIdparameter of the view object. This ensures that the whenever the page is displayed the country list correctly reflects the current region. Both pages' page definition references theConditionalValidationPageControllerclass as described in section 10.5.4.2 Customizing the Page Lifecycle for a Single Page of the ADF Dev Guide in order to avoid validating the row if the page request was caused due to the auto-submit of the Regions or the Country poplists. Also, this custom page controller overrides the prepareRender() method to conditionally set theCountryIdbinding to null if the user is changing the region poplist, detected based on the presence of the request-scopeRegionChangedattribute mentioned previously. Also note that the example contains a group of classes in thetest.view.bug5930745package to workaround Bug# 5930745 that causes a JSF selectOneChoice control to incorrectly display a blank entry when the value of a ADFM List Binding is null and it has registered exceptions. TheViewControllerproject in this example also implements the same custom error handling code as example# 107 and contains a slightly-modified routine in itsCustomFacesPageLifecycleclass for "dirtying" the first updateable, mandatory attribute binding found to have a null value. This avoids skipping validation when the user tries to save the row without changing any values. **NOTE:**fortunately all of this becomes easy and declarative in JDeveloper/ADF 11g!
- This sample works on the HR schema, but requires first running the supplied
- DynamicTabs1112
- DynamicTabs1212
- DynamicTabs11114
- 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(). TheTestClientprogram calls an application module's client interface method namedcreateViewObjectAndViewLinks(). 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.
- 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
- 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
Deptentity object based on theDEPTtable, we assume that in addition to theDeptnoprimary key's uniqueness that is declaratively enforced using the ADF UniqueKeyValidator, we also want to enforce the uniqueness of theDnameattribute 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". TheDeptDefImplclass in this example implements anexistsByDname()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 theFindDeptByUniqueDnameview object to test case-insensitively whether a row exists in theDEPTtable 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. TheDeptentity object class has an attribute-level method validator defined to trigger thevalidateDname()method in theDeptImplclass. This method gets the custom entity definition class and calls theexistsByDname()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.
- This example illustrates how to implement an efficient existence check to enforce the uniqueness of a non-primary-key attribute. Using a
- Entity and View Object Based on Web Service [10.1.3]
- This example contains two separate workspaces
DeptADFBCWebServiceandEntityAndViewBasedOnWebService. The former contains two projects. The first is namedProjectand contains a simpleDeptServiceapplication module, and a defaultDeptentity object, and entity-basedDeptViewview object. The application module has custom methods on its client interface likeretrieveDepartmentData(),estimateCount(),findDepartmentByDeptno(),insertDepartment(),updateDepartment(),mergeDepartment(), anddeleteDepartmentByDeptno(). TheDeptServiceapplication 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 theDeptADFBCWebServiceworkspace is aTestsproject 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 suppliedCreateEmpAndDeptTables.sqlin theSCOTTaccount. The WAR deployment profile in theProjectproject deploys the web service to an external OC4J instance, which you can launch most easily by running thestart_oc4jbatch file (or shell script) in the./jdev/binsubdirectory of your JDeveloper installation home directory. After deploying, you can test the web service by pointing your browser at the URLhttp://localhost:8888/DepartmentServices/DeptServiceSoapHttpPort. Note that the web service unit test fixture makes use of a web service proxy class namedDeptServiceSoapHttpPortClientthat was generated using JDeveloper's Web Service Proxy wizard, using the WSDL URL ofhttp://localhost:8888/DepartmentServices/DeptServiceSoapHttpPort?WSDLThe secondEntityAndViewBasedOnWebServiceworkspace contains anHRModuleapplication module, and default entity objects and view objects for theDEPTandEMPtables. TheDeptImpl.javahas 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, theDeptViewImpl.javaclass 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 theHRModule- and you make sure you have the webservice in the other workspace deployed and currently running - you can work with the data in theEmpViewandDeptViewview object instances. When the data is read for theDeptViewit 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.
- This example contains two separate workspaces
- Data-Driven Radio Group in an Emp JSF Table [10.1.3]
- This example illustrates an ADF Faces table showing rows in the EMP table, where the Deptno attribute in each row is indicated with a data-driven radio group. The page also illustrates the automatic data-driven radio group you can get for a single-row form by dropping the "Deptno" attribute of the "EmpView" view object from the Data Control Palette as an "ADF Single Select Radio" control. When using the radio group inside a table, you can see that the tags are slightly different since the current value of the radio group is given by the EL expression #{row.Deptno} instead of an EL expression the references a binding directly. The list of values for the radio group is provided in both cases by the DepartmentList table binding in the page definition, based on the corresponding iterator binding pointing to the DepartmentList view object instance in the data model.
- EntityAndViewBasedOnWebService
- 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
Deptentity in the project has published an event namedOnDnameOrLocChanged. 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 theDeptImpl.javaclass, you can see that I've added a call to thisOnDnameOrLocChanged()method inside thesetDname()andsetLocmethods. 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 theDeptDefImpl.java, you'll see generated methods toaddOnDnameOrLocChangedListener()andremoveOnDnameOrLocChangedListener. 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 theadd*EventName*Listener()method. TheEmpentity in the demo declaratively subscribes to theOnDnameOrLocChangedevent, indicating that the event should be delivered to all associatedEmpentities 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 theAppModuleapplication module and try changing the value of theLocorDnameattribute of a department, you can observe in the JDeveloper Log window that the associatedEmpentities in that department receive the notification.
- This example illustrates one way to use the lightweight JavaBeans event publish/subscribe mechanism that ADF Business Components supports for entity objects. The
- Entity Object Based on View With Instead Of Triggers Avoiding Returning Into Clause
- Illustrates the one-line of code needed in a custom entity definition object to indicate to the ADF framework that you don't want a particular entity object to use the
RETURNING INTOclause when it tries to refresh-on-insert or refresh-on-update. TheRETURNING INTOclause throws database-level errors when used in some kinds of database views havingINSTEAD OFtriggers. Also shows that you need at least one attribute in the entity other than the rowid marked as "Unique" to make the insert situation work correctly.
- Illustrates the one-line of code needed in a custom entity definition object to indicate to the ADF framework that you don't want a particular entity object to use the
- Best Practice Approach for Invoking AM, VO, or VO Row Methods from a Backing Bean [11.1.1.1, SCOTT schema] 18-SEP-2009
- This example illustrates several interesting points about how the view-controller layer can use ADF action bindings to invoke custom methods exposed on the client interface of application modules, view objects, and view rows. Run the
ViewControllerproject to start the demo. Enter a string value and an integer value on theStartPageand click the button to start theemp-task-flowtask flow, passing in values for the task flows two parametersstringTaskFlowParamandintTaskFlowParam. In theTestPage.jspxthat runs whenemp-task-flowstarts, the parameter values passed in appear in the title bar of the box at the top. Nine buttons in this page illustrate different combinations of invoking application module, view object, and view row methods using action bindings in the page's pageDefinition. For the methods that accept arguments, the nested elements inside the action binding (which you can see in the structure window) reflect the names of the method arguments and provide a declarative EL expression that ADF will evaluate when the action binding is executed to supply the method arguments. Three of the nine buttons are bound to action event handler methods in theTestPagebacking bean. This backing bean illustrates the best-practice technique to invoke methods on the AM, VO, or VO Row client interface, optionally providing some or all of the method arguments in code as well. In particular, it illustrates that you should NOT use theConfiguration.createRootApplicationModule()API to access an application module in your backing bean. See this blog article for more info on why you should not use it in backing beans. For a bit more information on how theStartPagecaptures and passes parameters to the task flow, read on. The initialStartPage.jspxuses page definition variables namedpageDefStringVariableandpageDefIntVariableto declaratively provide temporary storage for the string- and int-valued parameters in the parameter form. These variables were added to the pageDefinition using the Structure window by selecting the variables node inside the executables section, and choosing *{ Insert inside variables > variable }*from the right-mouse menu. Also in the structure window for the page definition of the Start page, we created two attribute bindings to expose the values of the pageDefinition variables to the UI. One way to create these bindings is to select the bindings folder in the Structure window and choosing { Insert inside bindings > Generic Bindings > attributeValues }. The other way is to use the "Bindings" overview editor tab for the StartPage and click the Create Control Binding icon (green plus-sign) in the Bindingsbox on the left. When creating the bindings, choose the iterator binding namedvariablesand pick the pageDef variable name whose value you want to bind to as the attribute name. Theaf:inputTextfields in theStartPagebind to this attribute bindings using the EL expressions#{bindings.pageDefStringVariable1.inputValue}and#{bindings.pageDefIntVariable1.inputValue}. The button on theStartPagecontains two nestedaf:setActionListenercomponents to assign the values of the pageDefinition variables collected from the user into two request-scope attributes. The value of#{bindings.pageDefStringVariable1.inputValue}is assigned to#{requestScope.pageDefStringVariable}, and similarly the value of#{bindings.pageDefIntVariable1.inputValue}is assigned to#{requestScope.pageDefIntVariable}. The task flow call activity namedemp-task-flowin theadfc-config.xmlunbounded task flow is configured to assign the values of the task flow parameters from these request-scope attributes. ThestringTaskFlowParamtask flow parameter gets its value from the#{requestScope.pageDefStringVariable}, while theintTaskFlowparam gets its value from the#{requestScope.pageDefIntVariable}. As part of its parameter definitions, theemp-task-flowitself defines pageFlowScope attributes that will hold the values of the task flow input parameters for the duration of the task flow. ThestringTaskFlowParamparameter value is stored in the attribute#{pageFlowScope.stringTaskFlowParam}while theintTaskFlowParamis stored in the attribute#{pageFlowScope.intTaskFlowParam}. Any pages or backing beans that execute in the context of this task flow can reference the parameter values using these same EL expressions. As noted above, the action bindings in the page definition are configured to reference these pageFlowScope attributes using EL to declaratively pass their values as method arguments to the invoked method.
- This example illustrates several interesting points about how the view-controller layer can use ADF action bindings to invoke custom methods exposed on the client interface of application modules, view objects, and view rows. Run the
- ExplodedTreeBindingAccessedByIterator
- 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 theModelproject, The technique involves: (1) exposing thegetPostedAttribute()API aspublicin aCustomEntityImplframework extension class since otherwise the method would be protected, (2) automatically adding a "shadow" attribute named*OrigAttrName*_origfor each attribute in the view object (in the overriddencreate()method of theCustomViewObjectImplclass, and (3) returning the original value of the appropriate underlying entity attribute usinggetPostedAttribute()in an overriddengetAttributeInternal()method of theCustomViewRowImplclass. TheDeptentity is configured to use theCustomEntityImpland theDeptViewview object is configured to use theCustomViewObjectImplcomponent class and theCustomViewRowImplrow class. In theViewControllerproject, the technique involves referencing the "_orig" attribute names in the EL expressions for the values of certain UIComponents. Try navigating through multiple rows in theDeptViewand making changes to theDnameand orLocattributes 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.
- Section 9.9 How to Access Original Attribute Values in the ADF Developers Guide for Forms/4GL Developers explains the
- Exposing Entity Row State as View Row State on the Client in a Generic Way [10.1.3.2] 2006, Upd: 29-MAR-2007
- This example illustrates a generic technique, implemented in a combination of an extended ViewObjectImpl class and an extended ViewRowImpl class, that exposes a dynamic attribute named "RowState" on any view object that extends the custom ViewObjectImpl class. It uses addDynamicAttribute() in an overridden create() method in the ViewObjectImpl subclass to add the dynamic attribute, and an overridden sourceChanged() event to handle the notification of the change in row state for the underlying entity object. The custom view row class overrides getAttributeInternal() to return the value of the Entity.getEntityState() method (translated to a user-readable string value), as the value of the dynamic attribute. Note that the ViewObjectImpl custom class - counter to best practices! - needed to be placed in the oracle.jbo.server package because one of the API's required to implement this solution generically was not currently public. I've created Bug # 4547474 to track getting the appropriate API made public in the future.
- FaceletsAndSetPropertyListener
- Filter a Tree Showing Necessary Parent Nodes for Matches [11.1.1.1, SCOTT schema] 15-SEP-2009
- The
EmpViewview object in this example features a WHERE clause with a "reverse"CONNECT BYexpression to identify parent employee rows that match theEnamesearch criteria. TheSTART WITHclause filters employees in a case-insensitive way based on the value of thevarEnamebind variable. The built-inExecuteWithParamsoperator for theEmpViewwas dropped onto the page as a parameter form to declaratively apply the user's search filter and re-execute the query. TheEmpViewImplcustom view object class overrides the framework'screateViewLinkAccessorRS()method in order to set the value of thevarEnamebind variable from theEmpView1view instance in the data model to also be set on the framework-created view link accessor view object, as well as on any view link accessor rowsets created. This "cascades" the value of the bind variable to the nested queries appropriately. In the page definition for theFilteredTreeShowingInterimNodes.jspxpage, the automatically-createdExecuteWithParams_varEnamepage definition variable has a custom label hint associated with it to define the prompt that will appear next to the search field. Last but not least, theTracingViewObjectImplframework extension class instruments thebindParametersForCollection()method to dump useful information about each query executed. TheEmpViewview object specifies this class as its framework base class.
- The
- Selecting a Row to Edit from a Popup Dialog [10.1.3.1]
- The
EditDepartment.jspxpage in the example allows the user to edit a row in the DEPT table. A button on that page has itsActionproperty set todialog:selectDepartmentand has itsuseWindowproperty set totrueso that it invokes a modal, popup dialog containing the pageSelectDepartment.jspx. The commandButton on that page contains a nestedaf:returnActionListenercomponent 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.) TheonReturnFromSelectDepartmentDialogreturn listener method in theEditDepartmentbacking 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.
- The
- 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
CustomViewObjectImplthat overrides thebindParametersForCollectionmethod to conditionally uppercase any String-valued bind variable parameter values that happen to have a custom metadata property namedUppercaseset on them in their bind variable definition. You can use the view object editor to inspect the bind variable namedTheNameon both theDeptViewandEmpViewview objects to see that they both have thisUppercasecustom metadata property set. Both of these view object specifyCustomViewObjectImplas 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 whoseEnamestarts with the letter "s" (entered in lowercase, too).
- This example illustrates a framework extension class
- 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. TheDeptViewview object in the example indicates that it should use theMyViewRowImplclass as its view row implementation class. TheDeptentity object supplies default values for itsLocandDnameattributes, and theDeptViewview object specifies a further view-object-attribute-level default value for theLocattribute as well. You can use the ADF Business Components tester to try creating a new row to observe the behavior.
- 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
- Further Filtering View Link Accessor RowSets at Runtime [10.1.3.1] 08-FEB-07
- The
test()method in theTestModulein 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 runtimeWHEREclause 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 theTestClient.javaclass to see the results of thetest()method in action.
- The
- Accessing Attribute Definitions on Source and Target of a View Link
- This example contains an application module method called demonstrateAccessingViewlinkAttributes() which illustrates the coding technique you can use to access both the source and target attribute definitions involved in a view link. Run the test client to invoke this client-exposed method in the appropriate way, using the generated client TestModule interface, and the output will show in the console.
- Getting the Formatted Version of an Attribute's Value
- This small example contains one EmpView view object whose Sal attribute has an associated format mask of $0000.00. To see the format mask visit the view object wizard, click on the Sal attribute, then see the "Control Hints" tab in the editor. The Test.java class in the project shows how to access the AttributeHints object associated with any attribute definition,by calling getUIHelper() on it,and call its getFormattedAttribute() method to get the formatted value.
- GlassfishExtension
- Globally Changing the Default Number Format
- This small example illustrates one approach to globally change the default format mask for number attributes. It uses a custom EntityDefImpl class to programmatically override the resolveDefObject() method and set the FMT_FORMAT and FMT_FORMATTER properties attribute definition property map of any entity object attributes definitions of entity objects that use this custom entity definition class.The same technique could be applied for date attributes
- Synchronizing Emp Details with a Dept/Emp Tree [10.1.3.3] 21-FEB-2008
- The
Example.jspxpage in this workspace illustrates a tree based on theDepartmentsview object instance. TheDeptViewview object definition on which this view instance is based, is viewlinked to theEmpViewview object with a view link accessor namedEmployeesInDepartment. The tree binding in the page definition is configured with two rules in order to show theDnameattribute for theDeptViewrows, to "drill down" into theEmpViewdetails for eachDeptViewrow using theEmployeesInDepartmentview link accessor attribute, and to display theEnameattribute for eachEmpViewin the tree. The tree control has anidofmyTreeso that the panelGroup component surrounding the employee detail information can have itspartialTriggersproperty 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 therenderedproperty 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. ThenodeStampfacet of the tree component includes answitchercomponent 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 expressionnode.hierType.viewDefNamewhich 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 theDeptViewview object, and a string of "test.model.EmpView" for the nodes coming from theEmpViewview object. In order to avoid using these "raw" view definition names as theswitchercomponent's facet names, we introduce atreeLevelmap in theExamplebacking 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 thefaces-config.xmlfile using the JSF managed bean facility. ThefacetNameproperty 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,DeptViewnodes render using the contents of theDeptNodeswitcher facet as a outputText, whileEmpViewnodes render using the contents of theEmpNodefacet as a commandLink. The command link is configured to have its action listener invoke the declarative action bindingsetCurrentRowInEmployeesIteratorWithKeywhich is the name of the action binding in the page definition that uses the built-insetCurrentRowWithKeyoperation against theEmployeesIteratoriterator 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 theExamplebacking bean, theonTreeNodeDisclosedmethod 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. TheonClickEmployeeCommandLinkis 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 itsimmediateproperty 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. [NOTE: An 11g version of this example that has been migrated to use the Apache Trinidad components is available here.]
- The
- Declarative and Programmatic Techniques to Pass Arguments to Method Action Bindings
- When you have a button that invokes a method in your data control, there are two ways you can pass the parameters: declaratively and programmatically. This small example contains two runnable Swing frames that illustrate each technique. The Form.java class illustrates the programmatic technique of adding an action binding listener for the action binding and setting the parameters list in the beforeActionPerformed() method. The FormDeclarative.java class uses a JTextField that is bound to a data control created for the simple MyBean class to hold a transient property value. The UIModel for the FormDeclarative page has a "sayHello" action binding, whose nested parameter definition refers declaratively to the value of the text field's binding object using the expression FormDeclarativeUIModel.name. In both cases, if you type your name into the text field and click the button, "Hello, YourName" appears in the log window. Note that the "sayHello" action binding has its "Requires Update Model" property set to true so that the value in the current field is applied to the model bindings before the method is invoked.
- Using a Headless Taskflow to Perform Work in an Autononmous Transaction [11.1.1.5] 24-NOV-2011
- This example illustrates a technique to use a "headless" taskflow -- that is, one without any view activities -- like a subroutine call. The
perform-isolated-workbounded task flow in the example has its Data Control Scope set to "isolated" so that the work it performs is done in a separate transaction. Run theMain.jspxpage to try the demo. Theexample-dept-regionbounded task flow includes a button on itsExampleDept.jsffpage that navigates to a task flow call activity in the taskflow to perform the work done by the isolated "subroutine" call. Theperform-isolated-workincludes a method call activity that invokes theperformAppModuleLevelWork()client interface method in theAppModuleapplication module. This method accepts an integer representing the department number to modify, and a String representing the value that department'sLocattribute should be updated to, then it commits the changes. The taskflow accepts parameters which it passes into this method call. Theaf:commandButtonincludes two nestedaf:setPropertyListenercomponents to assign values to therequestScope.deptnoandrequestScope.locValueattributes which are referenced by the task flow call to pass these values into the task flow. The page is configured to pass the current row'sDeptnovalue, and to pass the literal value 'Q' as the value to assign to theLocattribute in the current row. The net effect is that clicking the button will update the current department row to have the value 'Q' as itsLOCcolumn value (in a separate transaction. The checkbox in the page controls whether or not the Router activity will declaratively refresh theDeptView1Iteratoriterator in the page, or not, upon returning from the task flow method call. If you leave the box unchecked, you can observe the effect of the update committed by a separate transaction by attempting to update the current row in the UI after having clicked the button. You'll see an error that "Another user has change the row with primary key ...". If you perform the refresh, you'll see that the requery causes theLOCvalue updated in the separate transaction to be reflected in the web page. The custom PagePhaseListenerCalledTaskflowErrorReporterPagePhaseListener, which is configured in theadf-settings.xmlfile, ensures that any exception thrown in the nested taskflow gets reported to the binding container of the page that is marked as an exception handler activity. To see this exception reporting in action, use SQLPlus to lock the row in the DEPT table corresponding to the current row in the web page. Then, when clicking on the button to perform the work in the isolated transaction, you'll see a "Row Already Locked" exception in the UI.
- This example illustrates a technique to use a "headless" taskflow -- that is, one without any view activities -- like a subroutine call. The
- JClient Panel Allowing User to Supply Bind Variable Before Executing Query, Showing Results in JTable
- This example contains a DeptView view object having the where clause
**dname like upper('%'||:0||'%')**, that is a "zeroth" bind variable using the Oracle-style positional bind variable notation. The Panel1.java class was created by dropping a JScrollPane followed by dropping the DeptView1 view object instance as a Table from the data binding palette onto that JScrollPane. The "Go!" button was dropped from the data control palette as an Execute button to cause the query to execute. The field accepting the parameter is just an unbound JTextField named jTextField1. There is code added in two places in Panel1.java that is highlighted with the stringADDED CODEin the comment preceding it. The first added code short-circuits the initial execute query by setting the underlying view object's maximum fetch size to zero (0) initially, just before the call to refreshControl(). The second added code adds an ActionBindingListener to the action binding named "Execute" that got created when we dropped the "Execute" action from the data control palette. That listener has a couple of lines of code in itsbeforeActionPerformed()method that sets the maximum fetch size back to unlimited (-1) and sets the where clause parameter value by position.
- This example contains a DeptView view object having the where clause
- JClient JTable Using Range Paging Mode
- The Range Paging mode offers developers an alternative strategy for paging through large numbers of database rows in a view object. Using this mode, only the current page of rows is queried from the database and kept in memory. This simple demo illustrates a basic JClient form containing an PanelEmployeesView that contains a databound JTable that shows the Employee data from the HR schema. Note that the line in the PanelEmployeesView.java's jbInit() method that calls tableEmployeesView1.setModel() has been moved to the end of the method to make sure that executes after the JTable has been added to its JScrollPane. In this way, the automatic calculation of the range size will work as expected, based on how many rows the user can see in the table. The RANGE_PAGING_AUTO_POST mode is set on the view object instance in the AppModuleImpl.java class's overridden prepareSession(...) method. This variant of the RANGE_PAGING mode allows the combination ofquerying, viewing, scrolling, and updatingthe visible rows a page at a time, as well asmaking inserts and deletes to them (which change the rows in the current visible range).
- 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
Booleanattribute namedSelectedhas been added. TheViewproject 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 thesetTransactionModified()method to avoid dirtying the transaction unless the transaction related to the underlying application module is actually dirty. The companionMyCustomDataControlFactoryImplis required to instantiate the custom data control class, and theDataBindings.cpxfile references the fully-qualified class name of the custom data control factory class in theFactoryClassproperty of the<BC4JDataControl>element in the<dataControlUsagessection of that file. Run thePanel1class to see the code in action. Clicking on the Selected? checkbox toggles the value of the transient flag, as visible by the message that thesetSelected()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.
- 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
- Using XSQL Pages with ADF Iterators in a JSF Application [10.1.3.2] 22-MAR-07
- This example illustrates a
TestPage.jspxwith a button whose action navigates to an XSQL pageTestPage.xsqlto format the data in the iterator using XML/XSLT techniques. TheTestPage.xsqluses the custom XSQL action classtest.view.xsql.ADFViewObjectthat 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 afilter-mappingfor the*.xsqlURL pattern, (2) theDataBindings.cpxhas been modified in the code editor to contain an additional page mapping entry for the/TestPage.xsqlpath 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 theADFPhaseListenerthat is registered to be used by the Faces infrastructure). This makes sure that the request-scopedbindingsattribute is correctly set to reference the current page's runtime binding container.
- This example illustrates a
- Browsing and Editing ORDImage Columns with JSF/ADF [10.1.3]
- This example illustrates a simple browse page and edit/upload page for images stored in an Oracle table column of type
ORDImage. Run theCreateTable.sqlscript in thaeModelproject to create theIMAGE_TABLEtable. See theREADME.TXTfile in theViewControllerproject for some of the manual steps that were necessary to create the working example since JDeveloper 10.1.3 does not currently offer automatic design-time support for ORDImage attributes, even though the runtime support is there as the example illustrates.
- This example illustrates a simple browse page and edit/upload page for images stored in an Oracle table column of type
- 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.jspxpage 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 likepanelGroup. 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 FacesaddPartialTargetAPI. I initially created the graph tag by creating a regular (i.e. non-JSF) JSPX page, and dropping theEmployeesInDepartmentdata 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 theGraphtag'sdataattribute to reference the renamed graph binding. Finally, I edited the chart's visual properties by double-clicking on theBIGraphDef1.xmlnode 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 calledTotalCompwhich simply is the sum of theSalandCompattributes to provide an employees total compensation. Notice that you can edit theSalorCommvalues 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. TheEmpentity in theModelproject 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.
- 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
- JTable of Emp Rows With In-Place JComboBox Showing Department Names
- This example illustrates how to show the user a JTable with a join of information from the EMP and DEPT tables, allowing the user to click on the department name (e.g. RESEARCH) in the grid and get an in-cell JComboBox for selecting anotherdepartmentby name. There are three things going on in this demo of interest. First, is that the EmpView view object includes the Dept EO usage by reference, so that when the Emp.Deptno foreign key attribute value is changed, the referenced department gets automatically looked-up and changed accordingly. Secondly, the demo does not display the Emp.Deptno attribute or the Dept.Deptno attribute (named WorksInDeptno in the view), but only the Dname attribute. Thirdly, the JTable used in the PanelEmployees uses an on-the-fly override of the editingStopped() and prepareEditor() methods.
- Data-Driven af:selectOneChoice List Bound to a Managed Bean Property [11.1.1.1, SCOTT schema] 17-SEP-2009
Page1.jspxin this example illustrates how to bind anaf:selectOneChoicedropdown list to a session-scope managed bean property#{myBean.selectedDepartment}. Rather than using an ADF list binding (which is designed to target a row attribute or page definition variable), instead we create a table binding in the page definition (DeptView1) that is bound to theDeptView1Iteratoriterator binding and which exposes the attributes we want to use for the label and value in the list of valid choices (DnameandDeptno, respectively). Nested inside theaf:selectOneChoiceanaf:forEachloops over theList-valuedrangeSetproperty that the table/range binding exposes, and create the select list items based on the data in the rows of theDeptView1Iterator(which is bound to the default rowset of theDeptView1view object instance in theAppModuleapplication module.
- Looking Up Referenced Deptno Given Only the Referenced Dname
- This example contains an EmpView that joins editable information related to an Emp entity object, and reference information related to aDept entity object. It illustrates the overrides necessary to permit a user to type in the Dname of the related department and to have the application lookup that department by name and set the appropriate department foreign key attribute automatically. The TestClient.java program exercises the EmpView view object by "feeding" it an XML message containing a value for Empno, Ename, and Dname, then illustrates that the readXML() API can be used either to create a new row or update an existing row. Finally, it uses the writeXML() API to print out the XML for that new row and show how the related department information like the "Loc" value has been looked up by the built-in ADF view object reference mechanism. See the DeptDefImpl.java class for an example of a custom entity definition class that provides alternative lookup methods to the built-in findByPrimaryKey(). The overridden EmpViewRowImpl.java class uses this lookup method in its setDname() attribute to perform the lookup necessary.
- Master/Detail/Detail/Detail
- Illustrates a four-level master/detail/detail/detail data model based on the HR schema (Regions -> Countries -> Locations -> Departments) allowing the user to "Drill Down" from one level to the next across four different web pages.
- Method Action Invoking Managed Bean Method Without Making Bean a DataControl [11.1.1.5] 24-NOV-2011
- This example illustrates how to configure an ADFM method binding to invoke a managed bean method without having to turn the bean into a data control. Turning a bean into a data control just to invoke a bean method on it is one of the most common mistakes I see ADF developers doing. The
MyBeanbean is registered in theadfc-config.xmlfile and the method action binding in the page def forview1.jspxreferences the bean using theInstanceNameproperty of the binding. Note that the EL expression you provide needs to use the older-style with the dollar-sign rather than the pound-sign. Run the page in the example and click the only button in the page. You'll see the message "Foo" print out in the log window.
- This example illustrates how to configure an ADFM method binding to invoke a managed bean method without having to turn the bean into a data control. Turning a bean into a data control just to invoke a bean method on it is one of the most common mistakes I see ADF developers doing. The
- Model One JSP Checkbox Example
- This example illustrates a simple JSP page with no Struts controller in the mix displaying a couple of checkboxes, and the overridden updateModel() method in a custom lifecycle class to customize the handling for the "unchecked" value of a checkbox.
- Composite Entity Using Stored Procedure API to Create/Modify/Remove Master and Children
- This example includes a InstallTablesAndPackages.sql script to create the DEPT and EMP tables, along with a DEPT_SERVICE package that features a three-procedure API: add_dept(), update_dept(), and remove_dept(). The PL/SQL API accept an instance of the DEPT_T object type which contains a nested EMPS attribute of type EMP_T_LIST (which is a TABLE OF EMP_T type). The procedure handles inserting, updating, and deleting all dept and related-emp information. We're using DEPT and EMP here to represent two strongly-related tables which in the ADF layer are represented as two composed entity objects. The overridden doDML() method on DeptImpl illustrates how to have the DeptImpl handle the DML for both Dept and any modified children entities. The example tries to build on a common pattern where the view objects and entity select are accomplished against database views, while the entity object DML operations happen against the simple PL/SQL API. Both the Dept.Deptno and the Emp.Empno attributes are populated from DB triggers from a sequence, so the example code illustrates also how to simulate the refresh-after-insert behavior that the framework would normally perform on your behalf
- 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
EmployeesViewview 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 theDemoModulein the ADF Business Components browser and double-click on theEmployeesview 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 theAllDepartmentsview 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 theDepartmentId. 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.
- This example illustrates an
- 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. TheStaffview object is an entity-based view object based on theUserentity object that has a WHERE clause to retrieve only the users having aUSER_ROLEis either'technician'or'manager'. TheProductExpertiseAreasis 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 theProductentity object as its primary entity usage, and hasExpertiseAreaas a secondary, reference entity usage. It defines a named bind variableBind_UserIdthat is consciously named exactly the same as the system bind variable the framework will add for the view link betweenStaffandProductExpertiseAreas(based on theUserId). That view link has a customized view link SQL clause to allow theUSER_IDto beNULLso 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 theProductExpertiseAreasview object will have a non-nullExpertiseAreaentity 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, theExpertiseAreaentity row part will be a blank entity row. To simplify the client, we introduce a transientBoolean-valued attribute on theProductExpertiseAreasview object namedHasExpertise. We override thegetHasExpertise()andsetHasExpertise()methods in the view row class to handle retrieving and setting this transient attribute. The setter method handles either creating a newExpertiseAreainstance corresponding to the currentuserIdandprodIdcombination, or removing an existing entity row, depending on whetherHasExpertiseis 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 BooleanHasExpertiseproperty, and the functionality works the same in JSF, JSP, or Swing. TheViewControllerproject contains a simple JSF page that displays a table containing aselectBooleanCheckboxbound directly to theHasExpertiseattribute. In other words, it is not using a specialtableSelectManycomponent 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.
- 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
- Implementing OK or Cancel with Task Flow Transaction & Savepoint Support [11.1.1.0] 20-DEC-2008
- This example illustates three bounded task flows that use different declarative transaction options. The
manage-employeestask flow has itstransactionproperty set tonew-transctionto indicate that it should only be used as a top-level task when no other current transaction is in effect. Themodify-employeetask flow has itstransactionproperty set torequires-existing-transactionto indicate that it only makes sense to be called as part of an existing transaction (but cannot be called on its own), since it requires parameters to work correctly. Thecreate-departmenttask flow has itstransactionproperty set torequires-transactionwhich allows it to be used either as a top-level transactional flow, or else as a part of another task flow with a transaction already in effect. To run the example, run theViewControllerproject. The home page has links that start either thecreate-departmenttask flow, or themanage-employeestask flow. As part of the task of managing employees, creating or editing an employee calls themodify-employeetask flow. While modifying an employee, if you need to create a new department, thecreate-departmenttask flow is called. The 'Cancel' return actions of themodify-employeeandcreate-departmentare configured to have therestore-save-pointproperty set to true so that, if they are not the task flow that is controlling the transaction, then they will use savepoints to allow canceling any pending work performed in that flow without rolling back the entire transaction. Experiment with performing some changes and doing different combinations of (OK) and (Cancel) buttons to see the effect of the nested transaction support. Before deciding to save or cancel all changes you have made to employees, you can see the modified rows' data in italics in the table, with the modified attributes in bold/italic. This display is facilitated by the use of custom row-specific attribute hints namedrowStateandvalueChangedthat are enabled due to the use of theCustomViewRowImplframework extension class in theFrameworkExtensionsproject. TheCustomViewObjectin that project works around a couple of issues in the 11.1.1 release related to the quick query component (forcing the view criteria item operator to be "Starts With" instead of "Like", and working around bug# 7660871 which causes the quick query criteria to not be applied correctly in some situations). TheCustomEntityImplin the project implements a generic solution for declarative control over the posting order of associated (but not composed) entities by allowing an entity to specify a customPostAfterAccessorsproperty whose value is a comma-separated list of association accessors which should be checked for a new referenced row that should be posted before the current entity. TheEmpentity in the example is configured with that property in order to cause a new, referencedDeptentity instance to post first.
- This example illustates three bounded task flows that use different declarative transaction options. The
- Creating ViewLinks Between ViewObject Instance in Different Application Modules at Runtime
- This sample illustrates some generic code in the ExtendedApplicationModuleImpl class in the project which introspects custom property metadata to create view link instances between a master view objectinstance in the current application moduleand a detail view object instance that can be in the current module or any nested application module instance. Using this to create view link instances between view object instance in the same application modules is not that interesting since you can set those up at design time using the application module editor. However, creating view links between a view object in the current AM and another VO instance in a nested AM cannot be done at design time or by hand-editing the XML. It needs to be done in code. See the custom properties of the DeptModule AM in the example for the information that the generic code is leveraging to setup the runtime viewlink.
- Non-Linear Navigation in Details Page [11.1.1.7] 14-AUG-2013
- This example illustrates a technique to allow a details region to navigate in a non-linear fashion among the results identified in a search region on a previous page. Both the search page and the details page uses the same
EmployeesViewview definition, but we use two distinct instances so that ADFBC can optimize the SELECT list for both use cases. The search page only shows theEmployeeId,LastName, andFirstNameof the employee, so only those three columns are selected from the database. In the details page, allEmployeesViewcolumns are bound to UI components (and reflected in page definition attribute bindings) exceptfor theManagerIdandCommissionPctfields, so theSELECTlist reflects this extended set of fields. TheEmployeesViewview object is marked to have SQLMode = "Declarative" so that ADFBC can calculate its runtimeSELECTlist based on the attributes bound in the current page definition. All of theEmployeesViewattributes except for the primary keyEmployeeIdare marked withIsSelected='false'(labeled in the design time user interface as "Selected in Query" = false. This allows the declarative SQLMode view object mechanism to prune these attributes out of theSELECTlist when they are not needed by the current page. The pageDef of the View2 page fragment contains a "RequeryDetail" action binding in the View2.jsff page's pageDef This is wired to the built-in action "ExecuteWithParams" The value of the VO's bind parameter comes from the EL expression#{bindings.SummaryEmployeeId.inputValue}. ThisSummaryEmployeeIdAttributes binding to the View2 pagedef to more easily bind to the EmployeeId attribute value in the current row of the summary VO instance's iterator binding The default activity of theemployee-detailstaskflow invokes this "RequeryDetail" action binding to execute the detail query when the task flow first starts. The DataBindings.cpx file is configured so that this method activity uses the same pageDef as the "View2" view activity that it forwards to. This is important so that the VO is executed in the context of the pageDef that has all the attribute bindings that will inform ADFM/ADFBC of what attributes to select. A ValueChangeListener in the View2.java backing bean to execute the "RequeryDetail" action binding Notice that when you run theHome.jspxpage, you can perform a search in the summary page to identify a set of desired results. Clicking on the (Details) button takes you to the details page. On the details page you can use the selectOneChoice "navigation list" at the top to navigate the current row in theSummaryEmployeesViewVO instance's result set. The ValueChangeListener in the View2 backing bean executes the "RequeryDetail" action binding to re-execute the detail query with the new bind variable value related to the new current row in the SummaryEmployeesView. If you click the (Summary) button, you return to the summary page with the current row reflecting the current row you had see in the details. In order to prevent any implicit executeQuery calls on theDetailEmployeesViewview object instance, we have set theRefreshproperty of theDetailEmployeesViewIteratoriterator binding in theview2page's pageDef to the value of "never". Since the default taskflow activity and the backing bean value change listener are already configured to (re)execute the VO query when we need it to, we do not need or want any implicit query execution to be performed (otherwise the VO might be executed with a null bind variable value and "waste" a trip to the database only to have no rows returned). TheTracingViewObjectImplclass logs the queries being executed to more easily see the declarative-mode SQL SELECT list pruning optimization at work.
- This example illustrates a technique to allow a details region to navigate in a non-linear fashion among the results identified in a search region on a previous page. Both the search page and the details page uses the same
- Avoid Adding a New Row to a Table Until Its Valid [11.1.1.2] 26-DEC-2009
- This example illustrates an approach to prevent a newly-created row from getting automatically added to a view object's rowset (shown in a table) until it passes all validation rules. Typically a newly-created row will be added to a rowset for any view object based on the same entity object. This example contains a framework extension class for entity objects
NotifyChangeOnValidatedEntityImpland a framework extension class for view objectsOnlyAddNewRowIfValidViewObjectImpl. The entity framework extension class overrides thevalidateEntity()framework method to send an attribute change notification after the entity object successfully passes validation. The view object framework extension class exposes getter and setter methods for a boolean property namedonlyAddNewRowIfValidand the overriddenrowQualifies()method ensures that a new row does not qualify for inclusion in the view object's rowsets unless it is valid. TheAppModuleImplclass overrides theprepareSession()method to set the property on theDeptView1view object instance. To run the demo, run theview1.jspxpage. Click (Create) to create a new row. A data entry form appears at the top of the page. To cause a validation error to occur, leave the fields blank, or try entering aDnamevalue of upper-caseXand aLocvalue of upper-caseY. Notice that until the row validates, it's not added into the table.
- This example illustrates an approach to prevent a newly-created row from getting automatically added to a view object's rowset (shown in a table) until it passes all validation rules. Typically a newly-created row will be added to a rowset for any view object based on the same entity object. This example contains a framework extension class for entity objects
- Triggering OnPageLoad-Style Code in a JSF Backing Bean Using ADF PagePhaseListener or PageController [10.1.3]
- This example illustrates two variations on an approach to have custom backing bean code be fired during the prepareModel phase of the ADF controller lifecycle (which is cooperating with the JSF controller lifecycle at runtime). The PageLoadExample.jspx page has a PageLoadExampleBacking bean. It implements the ADF PagePhaseListener interface. The page definition for the PageLoadExample.jspx page sets its ControllerClass property to the EL expression #{PageLoadExampleBacking} so that the ADF controller page lifecycle implementation delegates phase listener calls to the backing bean. The PageLoadExample2.jspx page is doing the same thing, except that its backing bean is inheriting from a base class that hides some of the code. This page also has a button that navigates to "AnotherPage" which is setup similar to PageLoadExample2 backing-bean-wise. The PageLoadExample3.jspx is using a backing bean that extends the ADF PageController class. It's pageDef controllerClass property is set to #{PageLoad3Backing} and this case illustrates that you can mix the backing bean goodness with the overidability of any aspect of the ADF page controller page lifecycle all in the same class. The onNext() method in the backing bean illustrates how the ADF page lifecycle will invoke an onXXX() method in the page controller class when an action binding named XXX is executed. This approach is how developers code event handlers in JSP/Struts PageController classes in 10.1.3 as well.
- Automatically Disabling Eager Coordination of Details Not Visible on Current Page [10.1.3]
- This example illustrates one possible idea for a generic technique to automatically disable master/detail coordination for detail view objects that are not displayed on the current JSF page. It might be relevant to consider when you have a "deep" or "wide" hierarchy of master/detail view objects in your application module data model, where the end-user will be navigating/changing master rows often, triggering automatic master/detail coordination based on the view link instances in your data model. By design, the business service layer has no knowledge of what a "page" is or what view objects in the data model are used by a given "page". By extending the framework's business layer and controller layer, you can supply information about the view objects in use in the current page's binding container to the business service to enable it to leverage this additional information to avoid eagerly querying detail data that is not visible on the current page. The framework extension class
CustomApplicationModuleImplcontains a methodenableDetailsForViewInstances()that accepts an array of view instance names representing the views displayed on the current page. It proceeds to explore the view link instances in the data model related to the supplied view object names, and enable/disable master/detail coordination as appropriate so that only the view objects in the supplied list are queried. TheExampleModuleapplication module extends this base class, and exposes the method on its client interface. In theViewControllerproject, theCustomJSFPageLifecycleclass overrides theprepareModel()method to augment this phase of page processing to add a call to the abovementionedenableDetailsForViewInstances()method, passing in a list of view instances corresponding to the iterator bindings in the current page's binding container. Another framework extension classCustomViewObjectImploverrides theexecuteQueryForCollection()method to short-circuit any attempt to query a detail view object when the framework-supplied named bind variable connecting it to the current master row has a null value. It accomplishes this by temporarily setting themaxFetchSizefor the view object to zero, calling the super, then restoring the originalmaxFetchSizevalue. The view controller project is instrumented with a customized DCJboDataControl in order to add educational log output at the beginning and ending of each request, and theCustomViewObjectImplclass overrides thebindParametersForCollectionmethod to log the execution of each query sent to the database. These two elements make it easier to observe which view object queries are getting executed on each request for educational purposes. The data model includes a main "CurrentEmployee" view over the EMP table, with a number of first-level, and one 2nd-level detail queries. The data in these detail queries is just dummy detail data queried again from cartesion products over the same EMP table to simulate various kinds of detail data. There are four JSF pages in demo:Home.jspx,Drill.jspx,AnotherPage.jspx, andThirdPage.jspx. Each shows some subset of the overall data model. Again for educational purposes, you can experiment with enabling or disabling the generic optmizations using the value of the AM configuration parameter namedenable.optimizations. TheExampleModulecomes with two different configurations, one that has this parameter enabled, and the other where its disabled. By selecting theDataBindings.cpxfile in theViewControllerproject, and selecting theExampleModuleDataControlnode under thedataControlUsagessection in the Structure Window, you can use the Property Inspector to set theConfigurationproperty to toggle between using theExampleModuleLocalconfiguration where the optimizations are disabled and theExampleModuleLocalOptimizationsEnabledconfiguration where the optimizations are enabled. The example is configured by default to use the configuration that has the optimizationsenabled. By experimenting with the various pages in the demo that present different parts of the overall hierarchy of view objects in the data model, you can observe in the Log Window the difference in which queries get executed as you navigate to different pages, navigate to different master rows with the (Previous)/(Next) buttons, drill down to third-level details, etc. TheThirdPagealso illustrates two techniques for forcing data in view objects to be requeried to have the user eagerly see the very latest data. The technique illustrated forEmpDetails5involves setting theCacheResultsproperty tofalseon its iterator binding. This causes the framework to perform aclearCacheon the view object at the end of the request. Requerying theEmpDetails6iterator is done using aninvokeActionin the page definition, bound to anExecuteQueryaction binding. ThisinvokeActionhas aRefreshConditionset to conditionally perform the data-refreshing query when the page is rendered, but not during post-back. In both cases you can observe when the data is refreshed by looking at the value of theCurrentTimecolumn in the tables. In your testing, make sure to visit all of the pages (even several times) and perform various levels of change master/detail current rows to get the full effect of the difference between the optimized and unoptimized cases.
- This example illustrates one possible idea for a generic technique to automatically disable master/detail coordination for detail view objects that are not displayed on the current JSF page. It might be relevant to consider when you have a "deep" or "wide" hierarchy of master/detail view objects in your application module data model, where the end-user will be navigating/changing master rows often, triggering automatic master/detail coordination based on the view link instances in your data model. By design, the business service layer has no knowledge of what a "page" is or what view objects in the data model are used by a given "page". By extending the framework's business layer and controller layer, you can supply information about the view objects in use in the current page's binding container to the business service to enable it to leverage this additional information to avoid eagerly querying detail data that is not visible on the current page. The framework extension class
- Optionally Filter Query Based on Presence of URL Parameter [10.1.3]
- This example contains a TestPage.jspx and TestPageTwo.jspx. The first one illustrates using a combination of an invokeAction executable in the page definition, bound to an ExecuteWithParams built-in action, to declaratively pass the value of the URL parameter named
dnameto the named bind variable on theDeptViewWithBindVariable. The second page illustrates an alternative technique that may be applicable if the where clause that needs to be added is too complex or too dynamic to create at design time. It uses a combination of an invokeAction executeable in the page definition, bound to a method action, to conditionally invokes either theclearFilterOnDeptView()or thefilterDeptViewByDname()on the application module's custom interface. Try tacking on an additionaldnameURL parameter to either of the pages like ?dname=acc or dname=s to see the effect of the filter. Intererstingly, the pages use the ADF Facesaf:switchercomponent to conditionally present the results in a table or in a form depending on how many results are identified by the query.
- This example contains a TestPage.jspx and TestPageTwo.jspx. The first one illustrates using a combination of an invokeAction executable in the page definition, bound to an ExecuteWithParams built-in action, to declaratively pass the value of the URL parameter named
- 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.sqlscript to create theOPTIONAL_REQUIRED_TESTtable, run theTestPage.jspxto see that when a row has itsRowTypeattribute set to the valueAthen theValueAinputText component renders, while if itsRowTypeattribute is instead set to the valueBthen theValueBinputText field renders. These fields set theshowRequiredproperty totrueto show the required field indicator to the end-user even though the underlyingValueAandValueBattribute are not marked as mandatory. The conditional mandatory validation is performed in theTestEntityentity object using entity-level method validators. The radio group UI component is marked to have itsautoSubmitproperty true, and theValueChangeListenermethod 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 theConditionalValidationPageController- 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 theControllerClassproperty 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'srenderedproperty. 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 itspartialTriggersattribute 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.
- This example illustrates how to validate and render conditionally-required attributes. After running the included
- Passing User-Entered Data in 'Non Database Block Fields' to Stored Procedure/Function
- This example presents a very simple JClient panel that allows the user to type into three "dummy fields" and contains two different buttons that are bound to data control methods. Both of these data control methods are implemented in the ExampleModuleImpl class. It required no user coding on the client to implement. The "non database block" view object was created using the view object wizard, selecting the "Rows Populated Programmatically, not Based on a Query" radio group on Step 1 of the wizard (this choice is new in 10.1.2). Then I added the transient attributes, defining their name, type, and marking them to be updateable = always. The form was thencreated using the ADF/JClient Panel Wizard, then the buttons were added by dropping data control methods as buttons onto the panel. The action bindings created to bind the buttons to the data control methods have their "Requires Update Model" property set to true. One of the data control methods invokes a stored procedure, passing the user-entered values, and the other method invokes a stored function, setting the function return value into another "dummy field". This example illustrates several interesting ideas. One is using a view object with only transient attributes as what Oracle Forms users might think of as a "Non-Database Block". There is a custom framework extension class CustomAppModuleImpl.java that illustrates a simple example of how to write generic framework code (like insuring that a blank row exists in a "non-database block" view object) based on whether or not a custom ViewObject property named InsureEmptyRow is present or not. The NonDBBlockview object in the sample contains such a custom property to cause the generic functionality inherited from CustomAppModuleImpl to kick in. The CustomAppModuleImpl.java also contains some generic helper code to simplify invoking stored procedures and functions that have bind variables.
- ViewRow and EntityObject Polymorphism
- Demonstrates the different levels of polymorphic query support that we have in ADF Business Components. The
TestClientexample uses an instance of a "People" VO but illustrates that the client can cast "MenRow" rows to the MenRow interface supporting agetManAttr(), and "WomenRow" rows can be cast to aWomenRowinterface to access agetWomanAttr()method that is specific to women. ADF Business Components supports two distinct kinds of polymorphism: ViewRow polymorphism (which you setup at the application module level) andEntityObjectpolymorphism (which you setup on an individual VO). This example shows both kinds of polymorphism at work, but they can be used independently.
- Demonstrates the different levels of polymorphic query support that we have in ADF Business Components. The
- Programmatic Use of Application Module Pooling API 2005, Upd: 02-MAY-2007
- This is a JDeveloper 10.1.3.2 update of the TestPoolServlet example that used to ship with JDeveloper 9.0.4 and before. It illustrate how to make correct, programmatic use of the Application Module Pool in your own code if necessary, and how to dump AM pool statistics programmatically.
- Understanding How Pooling Parameters Affect Runtime [10.1.3]
- This one-page JSF example is instrumented to print out console log messages related to the ADF beginRequest(), afterConnect(), prepareSession(), passivateState(), activateState(), reset(), and endRequest() methods. By changing application module pooling configuration settings and re-running the page, you can easily see the difference in the log output to better understand what is happening in the framework differently based on those configuration setting changes. For more details on ADF application module pooling, see Understanding Application Module Pooling Concepts and Configuration Parameters
- 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.jspxpage illustrates how to use aninvokeActioncombined with anExecuteoperation binding (and appropriate settings for theRefreshandRefreshConditionproperties of theinvokeAction) 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. TheAnotherPage.jspx, to which you can navigate fromDepartments.jspx, contains twoaf:commandLinkcomponents that navigate back to theDepartments.jspxpage. One of those links uses a nested,af:setActionListenercomponent to declaratively set the value of the request-scope attribute namedrefreshFlagto the valuetrue. The presence of this flag attribute causes theinvokeActionmentioned above to force a requery of the rows. TheDeptViewview 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 anaf:tableand have a range size ofNset on your iterator binding to show onlyNrows per page, then the estimated row count query will be used since the table component needs that count to build its paging control. TheDepartmentsProgrammatic.jspxpage is nearly identical to theDepartments.jspxpage, 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. TheDepartmentsAlwaysRequestOnPageEntry.jspxpage 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, theDepartmentsTimedAutoRefresh.jspxpage illustrates how to use the combination of anaf:pollcomponent and anExecuteaction binding to refresh the page without user intervention every 5000 milliseconds (i.e. 5 seconds). Notice that theaf:pollcomponent has anidattribute set to the value "timer" and that anaf:outputTexton the page as well as theaf:tableUI components list this "timer" id in theirpartialTriggersproperty so that they will be partial-page refreshed to "repaint" any updated results. Theaf:outputTextjust 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 theExecuteaction 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 theDepartmentsIteratorusing the built-in operation namedExecute.
- This example contains four JSF pages that each show a table of department rows. The
- Programmatically Scrolling the JSF Table's Current Page of Rows [10.1.3.1, HR schema]
- The
ProgrammaticScrollJSF backing bean in this example illustrates three different approaches to perform programmatic scrolling of the 25 rows in the HR schema'sCOUNTRIEStable. Run theProgrammaticScroll.jspxpage 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.
- The
- Making String Attributes Use the 'StartsWith' Operator in QuickQuery [11.1.1.0] 12-DEC-2008
- In JDeveloper 11g, to create a "QuickQuery" search form you drag the All Queriable Attributes view criteria from the Named Criteria folder beneath any data collection in the Data Control Palette and drop it onto your page, choosing "Quick Query" from the component Create menu. It provides a one-line search form that allows the user to pick from any of the queriable attributes in the view object and perform a query. By selecting the related search binding in the Executablessection of the page definition, you can use the Property Inspector to set the default quick query attribute to the name of the attribute that user's will likely search on most frequently. They can then always use the dropdown field to choose a different attribute to search on. Bug 7639222 reports the fact that end-users are surprised that the Quick Query defaults to using the LIKE operator when searching - requiring, for example, that the end-user enter "k%" [including the percent sign] to find an Ename like "KING". The WorkaroundForBug7639222ViewObjectImpl framework extension class in this example illustrates how to change the default quick query behavior to use the "StartsWith" operator instead. This allows the user to simply type "k" in the search field to find "KING" as they would expect.
- Declaratively Toggling Display of PanelBox Based on Radio Group Value [10.1.3]
- This example illustrates a simple JSF page with a
selectOneChoiceand aselectOneRadio, each with its respective value bound to anInteger-valued backing bean property. Theswitchercontrols use the respective property value to toggle the display of an appropriate PanelBox, and thepartialTriggersproperty setup on the containingpanelGroupcomponent causes the panel to repaint when the value of the respective selectOneXXX component changes.
- This example illustrates a simple JSF page with a
- UIX Page with a Read-Only LOV for Selecting Department [10.1.2]
- This example illustrates a UIX page called EditEmp.uix where the user can see the DNAME value of the current employee's EMP row, but cannot edit it directly. They must click on the flashlight icon to popup an LOV to choose a new department instead. The EmpView includes the Dept as a reference entity and the EmpViewRowImpl.java class overrides the setAttribute(int,Object) method to suppress the attempt to set the Dname value. The LOV ends up setting the foreign key Deptno attribute, and the ADF view object reference mechanism faults in the correct DNAME value for that new foreign key value automatically. Setting the Columns property on the messageLovInput field was the trick I found to disallow edits by the user, without marking the field read-only (which has the side-effect of hiding the flashlight icon).
- Read XML Example
- Simple command-line utilities that illustrates how to use the ViewObject's
readXML/writeXMLAPI's. By passing appropriate command line arguments, it will dump the XML for a view object to a file, or read in an XML file and "ingest" the contents in the file and apply inserts, updates, and deletes (and engaging entity-object level business validation) as appropriate.
- Simple command-line utilities that illustrates how to use the ViewObject's
- Recalc Sum of Salary at the View Object Level
- This example illustrates a technique where a transient attribute of a view object is updated to reflect the total sum of some attribute of all the rows in the view object's default row set. The code to recalculate the sum of the salary is in the getSumOfSal() method in the EmpViewImpl.java class. The custom EmpViewRowImpl.java class for the view row implements the getter method for the SumOfSal attribute by delegating to this view object method. The EmpViewImpl class extends a base DeclarativeRecalculatingViewObjectImpl class that contains some generic code to enable declaratively indicating that one attribute's change should recalculate one or more other attributes. The EmpView defines the "Recalc_Sal" property to leverage this mechanism to recalculate the "SumOfSal" attribute. If you restrict the VO's results using the BC Tester tool, you'll see the sum of the salaries reflects the subset. If you add a new row or delete an existing row, the sum of sal is updated, too.
- Accessing Custom AppModule, ViewObject, and ViewObject Attribute Properties via EL in a JSP Page
- This one-page example contains examples of the EL expressions you can use to access the custom properties defined on an ADF application module, view object, and view object attribute from a JSP page. Run the "/EditDepartments" data page in the struts diagram to see the results. There are some comments in the EditDepartments.jsp page at the three places I'm using EL to refer to custom properties from different levels.
- Forcing an Iterator Over a Generic Bean Collection to Be Refreshed
- When working with the ADF Business Components data control, the view objects and entity objects have event notification in place that the ADF Business Components implementation of the ADF row set iterator responds intelligently to. So, ADF iterators working with ADF Business Components-based back-ends are always up to date with changes made to the collections. If you are working instead with data binding against simple Java classes and do something in your code to update a
Collection-valued property, you need to manually trigger the rebuild of the iterator. This sample illustrates the line of code required to do that in theResultsAction.javacustom data action class.
- When working with the ADF Business Components data control, the view objects and entity objects have event notification in place that the ADF Business Components implementation of the ADF row set iterator responds intelligently to. So, ADF iterators working with ADF Business Components-based back-ends are always up to date with changes made to the collections. If you are working instead with data binding against simple Java classes and do something in your code to update a
- Releasing an Application Module in Reserved Mode
- This small example application illustrates the one line of code necessary to indicate that your application module should be released to the AM pool in reserved mode (described more in this OTN whitepaper). This mode is not generally recommended - we recommend using the default managed state release mode - but since customers sometimes ask about reserved mode for upward compatibility, the TestPageAction.java class in this example illustrates how to do it. If you run in debug mode, you'll notice that the passivateState() and activateState() methods in the HRModuleImpl class are never called since passivation and activation is not relevant to an application module used in reserved mode.
- 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 thehandleWarning()notification when any business components warning is signalled in custom code. As illustrated in theDeptImplclass in the example, you signal a warning by constructing an instance of theJboWarningclass and passing it to theaddWarning()method of theApplicationModule. To distinguish between a warning and a purely information message, the example introduces a subclassInformationalMessagethat extendsJboWarningand thehandleWarning()method in theCustomFacesPageLifecycleclass reports the warning as aFacesMessagewith the appropriate severity. To experiment with the demo, run theTestPage.jspxpage and try entering the value "ERROR" for theDnamefield. That will cause an attribute-level validation to fail for that attribute. If you instead enter aDnamevalue 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.
- 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
- Performing Custom View Criteria Item Search Form Validation [11.1.1.2] 26-DEC-2009
- This example illustrates a framework extension class for View Objects that enforces additional custom validation on a view criteria's items such that the user cannot try to "outsmart" a selectively-required view criteria item having the "STARTS_WITH" operator by entering a leading wildcard operator (
%or_). It also shows how you might force the end user to provide at least three leading non-wildcard characters in the search criteria so that the index on the selectively-required column is more selective and hence more performant. To try the demo, run theTestPage.jspx. Try submitting the search form without entering any of the selective-required criteria items (EnameandJobin our example). You'll see an error asking the user to provide a value for at least one of those fields. If you try to provide a search value like%and click (Search), you'll get a custom exception saying that your search cannot start with a wildcard. If you enter two letters likesm(to find employeeSMITH) and click (Search), you'll get a different error telling you to please enter at least three characters.
- This example illustrates a framework extension class for View Objects that enforces additional custom validation on a view criteria's items such that the user cannot try to "outsmart" a selectively-required view criteria item having the "STARTS_WITH" operator by entering a leading wildcard operator (
- Displaying ADF BC Mandatory Field Errors Using UI Hint Labels [10.1.3.2] 05-MAR-07, Upd: 13-MAR-07
- The
TestPage.jspxpage in this example contains an ADF Form dropped from the data control palette based on theEmployeesview object. It consciously chooses to avoid performing client-side required-field validation by notsetting therequiredproperty of theinputTextcontrols (which defaults tofalse). Instead, it sets theshowRequiredproperty of the components to the same EL expression that would normally be used by the client-siderequiredproperty. 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. TheViewControllerproject 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.1of 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 thegetComponentClientIdmethod on theFacesCtrlAttrsBindingobject to retrieve the Faces component client id in order to construct aFacesMessagethat is specifically related to a given UI component, (2) the use of the ADF FacesLabeledFacesMessageclass to create aFacesMessagethat remembers the label of the component to which it's associated, and (3) the special-case handling ofAttrSetValExceptionerrors 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 thevalidateModelUpdates()method in theCustomFacesPageLifecycleclass in order to call a helper methodforceValidationOfNewRowWithAllNullMandatoryAttributes()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 theTestHomePage.jspxyou can running two different standalone create forms by clicking on an appropriate command button. TheCreateNewEmployeePage.jspxpage 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. TheCreateNewEmployeePageUsingAMMethodViaEntity.jspxpage 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 valueXXXXXin 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 theviewcontroller.util.ListBindingHelperto 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 theCreateNewEmployeePageand theCreateNewEmployeePageUsingAMMethodViaEntitypages 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 thegetComponentClientId()function of theFacesCtrlAttrsBindingreturns null if the binding has not previously "seen" a non-null value during the session as well as the fact that theFacesCtrlListBindingdoes not support agetComponentClientId()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.
- The
- Passing RowIterator of Selected Tree Node to AM Method [11.1.1.0, SCOTT(Modified) schema] 20-JAN-2009
- This example illustrates the correct way to operate on the possibly multiple view link accessor rowsets of a tree binding. A very common mistake developers make is that they write application module custom methods that operate on a view object instance in the datamodel, only to be surprised when the changes they've made are not reflected in the tree on the page. Their approach fails because the ADFM tree binding uses view link accessor rowsets rather than data model view link instances to work with detail rows. To understand the difference, read section 35.1.3 Understanding View Link Accessors Versus Data Model View Link Instances in the 11g Dev Guide. To make this point extremely clear, the example's
AppModulecontains only a single view instance in the data model calledDepartments. The data model does not contain any view link instance or any "Employees" view instance. While those are useful for some master/detail UI scenarios, they are not needed/used-by a tree binding. Instead, the tree binding materializes the employee rows in each department by directly interacting with eachDeptViewrow's view link accessor attribute, producing separateEmpViewrow sets for each of the distinct department rows that the user expands to see the details for. The example depends on a slightly modified version of the usualEMPandDEPTtables calledDEPT_RANKandEMP_WITH_RANK. The latter table contains one additional column namedEMP_RANKwhich is used to order the employees in a given department. You should run the includedCreateTables.sqlscript in your SCOTT account before trying the demo. A few interesting points that the demo shows off is the use of the genericTableSupportBeanwhich exposes some useful properties to the EL expression language likeselectedNodeRowIteratorandselectedNodeRowKey. The method action bindings in the page definition for theTreePage.jspxpage reference these properties in order to declaratively pass the correct RowIterator and the key of the selected row in the table to the application module custom methods which resequence the selected employee's rank either up or down. Also note that in the Tuning section of the General panel for theDeptViewview object, the Retain View Link Accessor Rowset checkbox is checked on. This setting is required for the tree binding to correctly reflect programmatic manipulations in the pending transaction made by developer-written code in the AM.
- This example illustrates the correct way to operate on the possibly multiple view link accessor rowsets of a tree binding. A very common mistake developers make is that they write application module custom methods that operate on a view object instance in the datamodel, only to be surprised when the changes they've made are not reflected in the tree on the page. Their approach fails because the ADFM tree binding uses view link accessor rowsets rather than data model view link instances to work with detail rows. To understand the difference, read section 35.1.3 Understanding View Link Accessors Versus Data Model View Link Instances in the 11g Dev Guide. To make this point extremely clear, the example's
- Restore Current Row After Rollback [10.1.3, SRDemo schema]
- This example illustrates a generic framework extension class for view objects (CustomViewObjectImpl.java) that overrides the beforeRollback() and afterRollback() methods in the base ViewObjectImpl class to cache the key of the current row and then restore the current row by key after the rollback. The application module contains a line of code in its overridden prepareSession() method which calls getDBTransaction().setClearCacheOnRollback(false); The (Rollback) buttons in the two example JSF pages are bound to backing beans that call a helper method named executeRollbackActionAfterDisablingExecuteOnRollback() inherited from a RollbackHelperBase class. This method first calls setExecuteOnRollback(false) on the binding container, then finds an action binding named "Rollback" in the current binding container and invokes execute() on it. The ADF Faces tables in the two different pages are setup with the "AutoSubmit" property set to true on their TableSelectOne subcomponent. Unrelated to the currency restoration, but interesting to note nonetheless, both tables have an explicitly-assigned "Id" property value so that other panel in the page can register a "partialTriggers" based on that property to cause an Ajax-style partial-page refresh whenever the current row in the table is changed. Note: This example uses the SRDEMO schema from the SRDemo sample application.
- Reusing Databound ADF Swing Panels with Different View Object Instances Using Model Parameters [10.1.3]
- The
EmployeePanelin 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 nameddcParamandrsiParam(where 'rsi' is short for RowSetIterator). The example includes four other ADF Swing panels that then reuse theEmployeePanel, each passing in appropriate values for thedcParamandrsiParamparameters. 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 theEmployeePanelautomatically appears there as a reusable component. When you drag/drop theEmployeePanelonto 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'sdcParamandrsiParamparameters. In this way, you can reuse the same panel with different view objects. You'll see a special "page" binding appear in the Executablessection of the including panel's page definition, along with metadata capturing the EL expressions you've entered. The example features aPanel1panel that reusesEmployeePanelto display the results of the data collection namedEmpView1inTestModule1DataControl. APanel2panel reuses theEmployeePanelpanel bound to the data collection namedAllEmployeesin theTestModule2DataControl, based on a different application module. ThePanel3panel illustrates that you can reuse theEmployeePanelfor a data collection that is a view-linked detail view object instance, in particular theEmployeesInDepartmentdata collection in theTestModule2DataControl. And finally, thePanel4panel shows that you can reuse theEmployeesPanelbound 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 namedEmployeesReadOnlyin theTestModule2DataControl, an instance of the non-entity-based (and hence read-only) view object of the same name.
- The
- Router Data Action
- Shows a generic, and simple, customization of the basic ADF
DataForwardActionto automatically use theString-based result of a declaratively-invoked business service method as the name of the Struts forward to use for "next page" navigation.
- Shows a generic, and simple, customization of the basic ADF
- Two Ideas to Handle JBO-35007 'Row Currency Changed' Exception [10.1.3.4, HR schema] 19-SEP-2008
- This example illustrates how to use a custom page controller class to override the
handleError()method to conditionally handle the JBO-35007 exception ('Row currency has changed since the user interface was rendered.') in a way that might be more useful to the end-user. This error can arise if the user accidentally gets the current row in and editor form out of sync with the current row in its underlying iterator. One classic way this can occur is if the user is running Internet Explorer and presses the [Ctrl]-[N] key to "fork" a new window with the current edit form (typically in an innocent attempt to view/edit two different rows side by side using two separate browser windows. Another way this error can occur is through use of the browser back button. To observe the custom behavior, try running thelistEmployee.jspxpage using Internet Explorer. Select an employee in the table and click the (Edit) button. When the edit form appears, press [Ctrl]-[N] to open a new browser window with the same form. Then, in that new window, press (Back to List), select a different employee row and click (Edit) again. At this point, return to the original window and click the (Submit) button on the edit form. Since this form is editing a row that is no longer the current row in the underlying iterator, a JBO-35007 error will be signalled, however theControllerClassproperty of theeditEmployeePageDefXML file is configured declaratively to use the custom page controllerRedirectJBO35007ExceptionToAnotherPagePageController(in thebug.controllerpackage) to handle the JBO-35007 and redirect to aproblem.jspxpage that tells the user something about what just happened, and gives them a way to get back to the list page. If you edit the value of theControllerClassproperty of theeditEmployeePageDefto be instead the name of theSetRequestScopeAttributeFlagForJBO35007PageControllerclass instead, then when you repeat the above scenario to cause the JBO-35007 error to occur you'll see that instead the page becomes disabled and only allows the user to return to the list page.
- This example illustrates how to use a custom page controller class to override the
- 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
autoSubmitproperty of theaf:tableSelectOnecomponent youraf: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 youraf:tableand anaf:panelFormthat displays additional information about the selected row in the table. The secret lies in configuring thepartialTriggersproperty of the component that you want to be updated when the table selection changes. In the example, you see that I'd assigned anidofmyTableto theaf:tablecomponent, and on theaf:panelFormcomponent I've listedmyTableas one of the component id's that should trigger a partial-page request "repaint" (of theaf:panelForm). To allow you to experiment with toggling theautoSubmitproperty of thetableSelectOneon or off at runtime, I've configured a simpleSessionSettingssession-scoped managed bean that has a single property nameduseAutoSubmit. By setting thevalueproperty of theaf:selectBooleanCheckboxat 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 theaf:tableSelectOnecomponent'sautoSubmitproperty, 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 anidvalue oftableAutoSubmitControlto the checkbox, and listed thattableAutoSubmitControlcomponent id in thepartialTriggersproperty of theaf: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, thepanelFormto the right is updated to reflect the values of the new current row. The (testCurrentRow) button is a bound declaratively to thetestCurrentRow()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 thegetDeptView1().getCurrentRow()method call inside that method already "sees" the new current row (and prints out itsDeptnovalue to the console).
- 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
- Set Binding to Attr Value from Selected SelectBooleanRadio Button in Data-Driven Button Group [11.1.1.5] 24-NOV-2011
- This example illustrates an approach to render a data-driven set of selectBooleanRadio buttons and to set a binding with a selected attribute value from the row corresponding to the radio button the user selects. A set of SelectBooleanRadio components in a group can be thought of as a list of boolean flags, where ADF Faces will ensure that only one of the radio buttons flag will be true in a particular group. I've setup the af:iterator to map the stamped out SelectBooleanRadio components to a Map<Integer,Boolean> using the af:iterator's status variable's index value as the key into this map. The SelectBooleanRadioHelper class encapsulates a Map<Integer,Boolean> of the true/false flags for the selectRadioBoolean controls in a group. It also handles updating the value of a binding (whose name you pass in the constructor) with the value of an attribute (whose name you pass in the constructor) when ADF Faces puts a true value into the map, indicating that the currently selected row. The example is using two pageDef variables
currentSelectedValue1andcurrentSelectedValue2as temporary storage for the chosen attribute value from the selected row. The corresponding attribute bindingscurrentSelectedValue1BindingandcurrentSelectedValue2Bindingare bound to these variables. Where these attribute bindings are being used in the demo, you could use any attribute binding that represented where you wanted to set the current value of the selected radio group.
- This example illustrates an approach to render a data-driven set of selectBooleanRadio buttons and to set a binding with a selected attribute value from the row corresponding to the radio button the user selects. A set of SelectBooleanRadio components in a group can be thought of as a list of boolean flags, where ADF Faces will ensure that only one of the radio buttons flag will be true in a particular group. I've setup the af:iterator to map the stamped out SelectBooleanRadio components to a Map<Integer,Boolean> using the af:iterator's status variable's index value as the key into this map. The SelectBooleanRadioHelper class encapsulates a Map<Integer,Boolean> of the true/false flags for the selectRadioBoolean controls in a group. It also handles updating the value of a binding (whose name you pass in the constructor) with the value of an attribute (whose name you pass in the constructor) when ADF Faces puts a true value into the map, indicating that the currently selected row. The example is using two pageDef variables
- 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
EmpViewediting form. TheEmpViewview object includes theEmpentity object as its primary entity usage, as well as theDeptentity object as a secondary, reference entity usage, in order to display the relatedLocvalue for the department to which the current employee is assigned. TheDeptnois bound to aaf:selectOneChoicecomponent whoseautoSubmitproperty has been set totrue. This causes a PPR postback whenever the end-user changes the value of the list. TheLocfield is displayed as a read-onlyaf:inputText, and has itspartialTriggersproperty set to the value of the id of theaf:selectOneChoicecomponent ("DeptnoPoplist") that should trigger the partial page re-paint of the thatLoc``af:inputTextcomponent. When you run the page notice that if you navigate between rows in theEmpViewthe 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-enabledDeptnopoplist, then the value of the correspondingLocfield 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 thePPRDemomanaged 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.
- This examples contains a single JSF page with an
- Serving a Filtered View Object Result as a Comma-Separated Values (CSV) File
- This example illustrates a JSP page allowing the user to filter the employee list using the ADF view object's built-in Query by Example functionality (leveraging one of the techniques described in my Creating Search Pages with Both Fixed and Dynamic Criteria article on OTN), and offers a button to download the set of employees as currently filtered by the user as an Employees.csvfile. Notice that the BrowseEmployees and the EmployeesAsCSV data actions are sharing a UIModel (not strictly necessary, but wanted to illustrate that it's possible). The UI model contains three iterator bindings over the EmpView1 view object instance. The FindEmpView1Iterator is forced into find mode by theline of code in the overridden prepareModel() method of the BrowseEmployeesAction.javaand is used by the find fields at the top of the page. The EmpView1Iterator is set to have a range size of 5 and is used by the table display to show 5 employees at a time. The EmpView1 table bindingrelated to this iterator only includes the Empo, Ename, Sal, and Deptno attributes as shown in the table.The CSVEmpView1Iteratoris set to have a range size of -1 (to iterate all rows) and has a related table binding that includes all the attributes. The EmployeesAsCSV.jsp page illustrates how to render a CSV result with a developer-determined file name that will appear in the browsers "Save As.../Open With..." dialog.
- Initialize Task Flow by Setting View Object Bind Vars from Parameters [11.1.1.1, SCOTT schema] 03-SEP-2009
- This example illustrates how to to use an
ExecuteWithParamsbuilt-in operation dropped onto a task flow method call activity that is marked as the default activity to initialize the task flow by setting some view object bind variable values based on task flow parameters passed in from the caller. TheTestTaskFlow.jspxpage has two buttons that are configured to invoke the bounded task flow namedshow-employees-for-dept, passing in the value of the department number whose employees should be visualized. The task flow defines a parameter namedp_deptnowhose value is stored into the pageFlowScope attribute namedp_deptnousing the EL expression#{pageFlowScope.p_deptno}. TheExecuteWithParamsoperation for theEmployeesByDepartmentview object instance (of typeEmpView) was dropped onto a method call activity that has been set as the task flow's default activity. TheEmployeesByDepartmentview object instance has been configured in the application module data model panel to declaratively apply the view criteria namedByDepartment, so when you drop theExecuteWithParamsoperation for this view object instance, the list of appropriate bind variables appears in the dialog. ThevarDeptnobind variable's EL expression is configured on theExecuteWithParamsbinding in the page definition to the expression#{pageFlowScope.p_deptno}to pickup the value to assign the bind variable from the task flow parameter passed in. If you right-click on the method call activity and choose "Go to Page Definition" notice that theEmployeesByDepartmentIteratoriterator binding'sRefreshproperty is configured to the valueneverto avoid the ADF framework's performing any implicit refreshing of the iterator binding before the action binding has a chance to set the view object bind variables.
- This example illustrates how to to use an
- 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.
- Showing View Object Attribute Names or Label Hints in JSF Table [10.1.3]
- This example illustrates one approach for binding a ADF Faces table to show the attribute names of an "EmpView" view object as its data, along with a checkbox that allows the user to multi-select which attributes they like in the table. The attribute metadata is populated into a transient "EmpViewMetadata" view object in the prepareSession() method of the application module. Two application module contains two custom methods. The retrieveMapOfSelectedAttributeNames iterates over the transient view object and returns a Map containing the attribute names and the selected flag. The resetEmpMetadataView resets the selected flag in each row of the transient view object back to false. Both of these buttons were exposed on the app module's client interface, and were dropped from the data control palette as command buttons. The selected checkbox was not created with a checkbox binding (which translates string-valued true/false values). Instead, I just dropped a selectBooleanCheckbox from the component palette and set its Value property to #{row.Selected} since the attribute name in the metadata view object that represents the Boolean-valued selected flag is named Selected. The table binding needs to ensure that it includes all the attributes from the EmpViewMetadata view object. Double-clicking on the declaratively bound button for retrieveMapOfSelectedAttributeNames I let JDeveloper create me a backing bean and I too the Map that results from invoking the retrieveMapOfSelectedAttributeNames method and put it in the sessionScope. The EmployeeTable.jspx page references this #{sessionScope.selectedAttributes.XXXX} expression for each column showing attribute XXXX as the value of the "rendered" property.
- Signal RowInconsistentException Correctly Across Activation/Passivation [11.1.1.6] 12-MAR-2013
- This example illustrates an approach to ensure that the RowInconsisentException is correctly signalled even if the AM used by the second user has undergone passivation and activation since the first user changed the row. First, it's important to understand the potential problem. Assume that two users U1 and U2 query up the DEPT row with DEPTNO=10. User U1 modifies the Dname in that row and commits. At this point user U2 is looking at a "stale" value in the page in her browser. User U2 proceeds to make her edit and clicks (Commit). In an ADF page implemented in the typical way, the user will correctly get a warning that "Another user has changed the row" as long as U2's application module has not undergone passivation and activation. If instead application load forces ADF to activate the AM's passivated state to service user U2's (Commit)-button click request, then the change made by user U2 is silently committed, potentially overwriting the changes that user U1. This occurs because the act of activating the AM state reads in current DB values of the queried rows, which now reflect the changes made by user U1 instead of the values that are in user U2's current browser page. The solution involves using a change indicator attribute and including that change indicator attribute in the web page as a hidden field. In the example, the
Deptentity object is based on theDEPT_WITH_OBJ_VERSIONtable. This is the standardDEPTtable to which has been added a single, additionalNUMBERcolumn namedOBJECT_VERSION. TheObjectVersionattribute in theDeptentity is marked as a 'Change Indicator' attribute, and it's also marked as a 'History Column' of type 'version number'. The history column setting tells ADF to automatically set the value of this column to 1 in a newly created row, and to increment the version number each time the row is modified and saved. The change indicator setting tells ADF to compare only the value of this attribute in order to determine whether the row has been changed by another user or not. In the absence of a change indicator attribute, ADF must compare the values of all persistent attributes which can take longer. Theview1.jspxpage uses thetr:inputHiddencomponent to include theObjectVersionattribute value in the page. By doing this, the object version of the row being edited by user U2 will be submitted to the server along with the other attribute values, and it will be used to compare against theObjectVersionattribute value of the row being edited. Since these values differ, theRowInconsistentExceptionis thrown as desired. Try re-enabling the AM Pooling to convince yourself that the technique will work under normal circumstances as well. To run the example, start by running theCreateTables.sqlscript to create theDEPT_WITH_OBJ_VERSIONtable. Then run theview1.jspxpage. Once the page appears in your default browser, copy the URLhttp://localhost:7101/SignalRowInconsistent/faces/view1and paste it into a different browser. For example, if Google Chrome is your default browser, paste it into Firefox or Internet Explorer. This will allow you to test having two distinct browser users using your application. Both browsers should be looking at the row for DEPTNO=10. In the first browser window, update the value ofDnameand click (Commit). Now the second browser is looking at a "stale" value for theDname. In this second browser, update the value ofLocand click (Commit). The user gets the expected error "Another user has changed the row with primary key oracle.jbo.Key[10]". TheAppModuleapplication module in the example has its 'Enable Application Module Pooling' configuration setting (jbo.ampool.doampooling) set to false for testing purposes. Your application module will never have this pooling setting disabled in production, but it is useful for testing the activation-safety of your application module by stress-testing the passivation/activation on each HTTP request.
- This example illustrates an approach to ensure that the RowInconsisentException is correctly signalled even if the AM used by the second user has undergone passivation and activation since the first user changed the row. First, it's important to understand the potential problem. Assume that two users U1 and U2 query up the DEPT row with DEPTNO=10. User U1 modifies the Dname in that row and commits. At this point user U2 is looking at a "stale" value in the page in her browser. User U2 proceeds to make her edit and clicks (Commit). In an ADF page implemented in the typical way, the user will correctly get a warning that "Another user has changed the row" as long as U2's application module has not undergone passivation and activation. If instead application load forces ADF to activate the AM's passivated state to service user U2's (Commit)-button click request, then the change made by user U2 is silently committed, potentially overwriting the changes that user U1. This occurs because the act of activating the AM state reads in current DB values of the queried rows, which now reflect the changes made by user U1 instead of the values that are in user U2's current browser page. The solution involves using a change indicator attribute and including that change indicator attribute in the web page as a hidden field. In the example, the
- 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.
- 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
- 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
MyServiceBeanin theModelproject 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 ofContactPOJOs (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 aContactis changed, theContact'supdatedproperty 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 theRowSetof data being managed by theRowSetIteratorof 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 theCacheResultsproperty is explicitly set tofalse, which is not the case in this example!) and then rebuilds theRowSetofRowobjects that wrap the actual data beans -Contactbeans in this example. TheseRowobjects 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 theexecuteQuery()in backing bean code, while the latter using a combination of anExecuteaction binding related to the method iterator and aninvokeActionexecutable whoseRefreshandRefreshConditionproperties have been set to control the ADF lifecycle phase during which theExecuteaction 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 thefindContactsByName(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 thenameSearchthat the end-user might apply to filter the results is kept in the session-scopedUserInfomanaged bean so it can be referenced by the method action on both theListPage.jspxand theEditPage.jspxpages. 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. TheFwkExtensionsproject 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. TheFindOrMergePage.jspxillustrates an example of performing data binding to a method result that returns a singleContactbean instead of a collection of beans (List), using the helper methodexecuteQueryForMethodIteratorto 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 theFindOrMergePagecan make updates as well as add new rows, theaf:commandLinkon the page sets the requestScope flag to signal to theListPageto refresh its data on navigating there.
- This example illustrates a simple JSF application that allows you to list, edit, add, and remove contacts. The
- SmartPanel Prototype Demo
- A customer asked me a few years ago to demonstrate how they could define databound JClient panels using simple XML files as a way to "design" the screens instead of designing them one by one in the visual designer. I defined an XML Schema called SmartPanel.xsd with a simple XML vocabulary of tags for defining a data-bound panel with an HTML-table style layout, as well as a few simple component types represented by tags named input, label, display, poplist. The SmartPanels project in the workspace contains the base SmartPanel class, which the EmpPanel class in the SmartTest project extends. The SmartPanel uses theSmartBuilder classwhich implements a SAX filter to dynamically build up the JClient binding objects based on the XML elements found in the panel definitionfile, as well as the Swing panel controls that are bound to them.The EmpPanel.pnl file in the SmartTest project defines the XML definition of the EmpPanel panel. If you visit the Tools | Preferences... and go to the XML Schema tab, you can add the SmartPanel.xsd file to the list of schemas your IDE is aware of, and relate it to the .pnl file extension. Then you can see how JDeveloper provides in-context, XML-Schema-driven code-insight for the custom XML vocabulary used to define the panels. Try commenting out the line in EmpPanel.java that sets the local to "US" and uncomment the line that sets the locale to Italian, then re-run. You'll see all the prompts show up in Italian. If you select a new department from the poplist, or select a new manager from the poplist, you'll notice how the ADF Business Components reference mechanism automatically refreshes the related information in the panel to show the related new department name, and/or new managers salary. It also causes the recalculation of the calculated attribute showing the current employees salary as a percentage of his/her managers salary. Also interesting is the declarative attribute recalculation going on in the EmpView view object. It extends a custom framework base class named DeclarativeRecalculatingViewObjectImpl, and the EmpView indicates a custom property named Recalc_Mgrwith a value of SalaryPercentageOfManager. This declaratively causes the SalaryPercentageOfManagerattribute to get recalculated whenever the value of the Mgr attribute gets changed, without having to writecustom Java code in the EmpViewImpl class to handle that. NOTE: I originally developed this example in JDeveloper 9.0.3 and have not upgraded it to use any new ADF binding features, but since we support upward compatibility for 9.0.3 JClient, it worked in 10.1.2 without any changes.
- Using a Custom Number Formatter to Parse/Format Social Security Numbers (SSN) [10.1.3.3] 31-AUG-07
- This example includes a
SocialSecurityNumberFormatterclass that extends the default ADF Business Components number formatter class (DefaultNumberFormatter). It overrides theparse()andformat()methods to implement the parsing and formatting of a United States social security number whose format is000-00-0000. The default number formatter does not work with this format mask as is because the JDKDecimalFormatclass on which it's based doesn't correctly support that format mask as you might expect. You'll need to run the providedCreateEmpWithSocialSecurityNumber.sqlscript to create a version of theEMPtable with an additionSSNcolumn to store the social security number as a numerical value. The Emp entity object sets the custom property namedSsn_FMT_FORMATTERto the fully-qualified class name of the custom formatter class. This property and its value are stored in the entity object's companionEmpImplMsgBundle.javamessage bundle class. TheCustomDCErrorHandlerclass in theFwkExtensionsproject contains logic that sets the attribute information on theDataCreationExceptionthat 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 theTestPage.jspxpage 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.
- This example includes a
- 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 callsetSortBy()on the iterator binding's underlying view object instance instead of the default of callingsetOrderByClause(). 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. TheViewControllerproject 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 theDataBindings.cpxfile. TheCountryListview object retrieves its data from the companionCountryList.propertiesfile. When you run theCountryList.jspxpage, try clicking the table headings to sort ascending or descending by theCountryCodeor theDescription. 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. TheNoDatabaseConnectionApplicationPoolImplclass 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 classNoDatabaseConnectionDatabaseTransactionFactoryis configured to be used by setting theTransactionFactoryproperty of the configuration, and it creates an instance of the customNoDatabaseConnectionDBTransactionImpl2class which overrides thedoRollback()method to do nothing.
- This example illustrates a technique to override the
- SortingFilteringByChoiceDisplayValue
- SplitterTest
- Enabling SQL Trace in Your Application Module to Get Query Tuning Statistics
- This is the example that goes with the Verifying Effectiveness of View Object Fetch Size Using SQL Tracearticle. It illustrates how to enable SQL Trace in the afterConnect() method of your application module if you don't fancy turning it on for your entire database instance.
- Programmatic View Objects Showing Master/Detail Data [11.1.1.0.0] 09-OCT-2008
- This example illustrates some generic framework extension classes in action for programmatic view objects whose data is related master/detail. The generic infrastructure code lives in the
StaticDataViewObjectSupportproject. All of the view objects in theModelproject specify theoracle.adfbc.staticdata.CSVFileViewObjectImplclass as their framework base class to inherit the generic functionality of reading their data from a CSV (comma-separated values) file. TheListOfMapsDataProviderViewObjectImplframework extension class implements a programmatic view object whose data is populated from ajava.util.Listofjava.util.Mapobjects. TheCSVFileViewObjectImplextendsListOfMapsDataProviderViewObjectImplto supply a "data provider" that reads data from CSV files. By convention, it reads data from the*.csvfile in the same directory in the classpath as the view object's component definition file. So, for example, themodel.Statesview object reads its data from themodel/States.csvfile. The compiler options of the project have been modified to add the*.csvextension to the list of files that should be copied to the outpath during compilation time. Four different JSPX pages in theViewControllerproject allow you to try out master/detail display of the programmatically retrieved data.
- This example illustrates some generic framework extension classes in action for programmatic view objects whose data is related master/detail. The generic infrastructure code lives in the
- Search Page with 'Sticky' Criteria Value Across Pages Using View Object Named Bind Variable [10.1.3]
- This example illustrates a simple search page over an EmpView view object with three named bind variables
EmpName,LowSal, andHighSal. The SearchPage.jspx was created by dropping the "ExecuteWithParams" action as a parameter form. It presents the results on a second ResultsPage.jspx. If the results were on the same page, then the ADF data binding layer would preserve the user's search criteria entry across postbacks to the same page. However, since showing the results causes page navigation, when the user returns to the search page, the search criteria are back to their default values. In this case, the named bind variables define their respective default values to be null, so this means the reset criteria is null when you come back to the page. If you want to have the user's search criteria for the named bind variable stay "sticky" across pages, then you can save it in an attribute in the process scope, and then assign the search field binding to the value of that processScope-saved value just before the page is rendered. The example uses a variation on theOnPageLoadBackingBeanBaseclass described in Using Custom ADF Page Lifecycle to Invoke an onPageLoad Backing Bean Method section of the ADF Developer's Guide for Forms/4GL Developers. TheSearchPage.javabacking bean overrides theonPagePreRender()method to set the values of the search field bindings to the value of the saved processScope attributes of the same names. TheControllerClassproperty of the search page's page definition references the backing bean as its page phase listener using the EL expression#{SearchPage}. ThesetActionListenercomponents on the buttons in the search page declaratively set the values of the processScope variables.
- This example illustrates a simple search page over an EmpView view object with three named bind variables
- Subclassing the ADFBC Data Control to Override begin/end-Request Method [10.1.3]
- This example illustrates a MyDCJboDataControl that extends JUApplication (which in turn extends the DCJboDataControl) so that it can override the beginRequest() method to perform some controller later code at the beginning of each request. There is also an endRequest() method that can be similarly overriden, but it's not shown in the example. The MyDataControlFactoryImpl.java overrides the default data control factory to return the name of the MyDCJboDataControl class, and the
DataBindings.cpxfile has been updated to reflect the name of this custom data control factory class. The demo doesn't do anything spectacular, but after clicking on the button in the test page to set a session level attribute, the conditional code in MyDCJboDataControl will invoke a custom method on the application module's custom interface passing in the value of the session attribute.
- This example illustrates a MyDCJboDataControl that extends JUApplication (which in turn extends the DCJboDataControl) so that it can override the beginRequest() method to perform some controller later code at the beginning of each request. There is also an endRequest() method that can be similarly overriden, but it's not shown in the example. The MyDataControlFactoryImpl.java overrides the default data control factory to return the name of the MyDCJboDataControl class, and the
- Simple Example of Runtime Component Substitution
- This workspace illustrates a simple example of a powerful ADF Business Components feature called runtime component substitution. The BaseProject project represents an application delivered by a software house or ISV containing ADF business components. The CustomizedProject represents a project that has performed some kind of on-site customization to the base application's components. The CustomizedProject has imported the com.somecompany.someapp package and created a new CustomizedView view object in its com.somecustomer.someapp package which extends the originally delivered view object component named ExpertViewObject in the base application's com.somecompany.someapp package. In the CustomizedProject, the component substitution list has been customized to indicate that com.somecompany.someapp.ExpertViewObject should be substituted by com.somecustomer.someapp.CustomizedView instead. This is done by editing the project properties in 9.0.5 and beyond, or in previous versions by editing the *.jpx node in the project. Doing a right-mouse "Test..." on the same SomeModule in both projects, you'll see that in the base project the query returns the number "1", while in the CustomizedProject the query returns the number "2". This illustrates that at runtime the indicated component substitution has been effected. You can also see the same effect by running the TestClient program in the base project, and running the CustomizedProject (which has been configured to have the BaseProject's TestClient class as its default run target). When running the base project, the test client program will print the result "1" to the console. When running it in the context of the CustomizedProject - whose Java VM arguments supply the jbo.project=CustomizedProject as a system parameter to point the runtime framwork at the project file where the component substitutions are defined - you'll see the same class, without recompilation or changes of any kind, produces the result "2" to the console.
- Generic Framework Extension to Suppress FIRST_ROWS Optimizer Hint in Range Paging Queries
- The MyCustomViewObjectImpl.java class in this little example illustrates how to write generic code in an overridden buildRangePageQuery() method which conditionally strips the FIRST_ROWS query optimizer hint out of the "wrapped" range paging query that the framework would normally build. Generally the FIRST_ROWS hint gives the best performance for thiscase(which is why we default it in there), but some users have found situations where they wanted to suppress it. The generic framework extension code calls the getProperty() method on the ViewObjectImpl class to see whether the view object developer has set a custom property named RangePagingFirstRows to the value N, and if they have, it strips the query optimizer hint before returning the range paging query. On the "Java" panel of the view object editor for the Employees view object, if you click the (Extends...) button, you can see that I've changed the base class for this view object component to use the demo.fwkext.MyCustomViewObjectImpl class instead of the default base class. If you visit the "Properties" panel of the view object editor, you can see where I've defined the custom property to make the conditional behavior "kick in" for this view object. Other view objects that extend our customized framework base class for view objects would continue to get the default behavior unless they also define that property.
- Custom Servlet Filter to Register a Globally-Available Data Control
- This example contains an example of how to register a "system" data control that needs to be available to the controller layer on each request, without having to register that data control in each application's DataBindings.cpx file. The scenario to imagine is some metadata-driven controller logic, which needs access to a "system" or "metadata" data control to accomplish its job. In the example, the DataPage1Action class simulates access to such a System Data Control in order to access a data collection that provides some database-queried "metadata" like the current database date, which it prints to standard out. Of course in a real example, this would be more interesting metadata that would help the DataAction decide what it should be doing on the current request. The SystemDataControl project in the workspace contains the InsureSystemDataControlFilter, which is a servlet filter that shows how to extend a base template filter class called AdditionalBeginOrEndRequestProcessingFilterBase to perform some additional custom processing at the beginning and ending of the request. TheInsureSystemDataControlFilter loads a "System.cpx" file to define the metadata for the system data control, and insures that it is registered in the binding context. It also illustrates how to access a custom data control parameter named ReleaseMode to generically detect whether the data control should be marked for being reset at the end of the request. Since the SystemDataControl in the example is an ADF Application Module, the ADF BC data control implements this reset() method as a stateless release of the underlying application module. Note that the sequential order of defining the servlet filters in the web.xml file is important here, particularly that the ADFBindingFilter come before the InsureSystemDataControl filter in the file. This will guarantee that the ADF Binding Filter will execute first, and the InsureDataControl filter second. The logic implemented in theAdditionalBeginOrEndRequestProcessingFilterBase guarantees that even if the filter is engaged multiple times in the same request, that the addition begin/end request processing only occurs at the initial entry into the filter and the final exit of the filter during the span of a single request.
- 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
DBTransactionImplclass which manages the counters in the UserData hashmap in the Session and a customEntityImplclass (used by theEmpEO in the project) which increments the appropriate insert, update, or delete counter in its afterCommit() method.
- 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
- Using a Transient Boolean Flag on a View Object to Mark and Filter Selected Rows
- The EmployeeList view object in this example is an expert-mode view object with no related entity. I've added a transient, Boolean-valued Selected attribute and written some encapsulated methods in the EmployeeListImpl.java class to support marking the selected attribute for a row by employee number. The data action event handling methods invoke custom application module methods to process the checked checkboxes. The SelectedEmployees page has an iterator binding based on the custom application module method getSelectedEmployees() which internally uses the getFilteredRows() API to return the subset of rows in the view object's rowset which have their Selected attribute set to true.
- Two Approaches to Referencing Controller-layer Session State in VO Bind Variables [11.1.1.2] 16-DEC-2009
- This example illustrates two different approaches to referencing controller layer state inside the default value expression of a view object's bind variable. One typical example is to reference the name of the logged-in user (which in the past web applications would store in a Web session attribute), however since you can use the
adf.context.securityContext.userNamegroovy expression to reference the username of the logged-in user when using ADF Security, I choose a slightly-different example of storing a code representing the user's favorite color. The ViewController project contains aUserInfobean with a singlefavoriteColorproperty. This bean is registered in theadfc-config.xmlfile as a session-scoped managed bean, and using the JSF managed property feature, the default value ofemgreenis injected into the bean at creation time. TheModelproject contains two view objects that each contain a bind variable namedVarFavoriteColorwhose default value we'd like to come from the current value of the aforementioned UserInfo managed bean'sfavoriteColorproperty. There are two basic approaches: one will appeal more to those who cherish the cleanest logical separation of view/controller and model layers. The other appeals more to developers who like to use the "simplest thing that works" (as long as it's not bad practice). TheExampleVO2VO instance in the AM data model is of typeExampleVOUsingADFContextSessionInfoInBindVariable. This view object'sVarFavoriteColorbind variable references the groovy expressionadf.context.sessionScope.UserInfo.favoriteColorand represents the "simplest thing that works" approach. This takes advantage of the fact thatADFContextobject abstracts access to the four interesting scopes that might be relevant during runtime of an ADF application:applicationScope,sessionScope,viewScope, andrequestScope. When running in the web container, these scopes map onto the obvious matching scopes that you are familiar with from the view/controller layer. When running outside the web container, the ADFContext provides a default implementation of these scopes as a set of static maps that are useful for regression testing purposes. TheTestclass in theTestingproject illustrates making use of theADFContext.getSessionScope()to setup the session-level information the view object is expecting to find at runtime. TheExampleVOin the AM's data model is of typeExampleVOUsingControllerSuppliedUserDataHashtableInfoInBindVariable. This view object's bind variable of the same name references the groovy expressionadf.userSession.userData.FavoriteColor. In this implementation that defines the more clear separation of view/controller layer and business tier - which is the one I personally prefer and recommend - the ADFBC session's userData map is used to store information that the view object's bind variable will reference. In a customized data control implementation class (CustomDCJboDataControl), thebeginRequestmethod is overridden to invoke asetSessionFavoriteColor()method on theExampleModuleclient interface to pass in the value of theUserInfo.favoriteColorinto the business tier. The application module stores this information in the user data map, and makes that information activation/passivation-safe by overriding thepassivateState()andactivateState()methods. The custom data control is configured by setting the fully-qualified name of theCustomDCJboDataControlFactoryclass in theExampleModuleDataControlentry'sFactoryClassproperty in theDataBindings.cpxfile (in thedataControlUsagessection). On each request, the view/controller layer passes this information into the business layer, and theExampleVOUsingControllerSuppliedUserDataHashtableInfoInBindVariableview object references its value from the userData map. Notice thesetDefaultValuesForSessionLevelFavoriteColor()method in theExampleModuleImplclass. This is invoked in an overriddenprepareSession()method to assign a reasonable default value to both of the favoriteColor elements if their value is currently null. This would ensure that both approaches would work if the respective view object were called from a service or a test client that didn't provide any specific value at runtime. In theTestingproject, theTestclass illustrates how you can write a standalone regression test (just a simple Java class in this example, not a JUnit test) which mimics the view/controller layer calling of the setSessionFavoriteColor() API in the one case, and which populates a "mock" sessionScope UserInfo bean with afavoriteColorproperty to make the other view object find its expected information. As mentioned above I prefer the approach that uses the userData hash table set explicitly via an application module method, however at least now you have a good example of both techniques in action so you can decide for yourself which you prefer.
- This example illustrates two different approaches to referencing controller layer state inside the default value expression of a view object's bind variable. One typical example is to reference the name of the logged-in user (which in the past web applications would store in a Web session attribute), however since you can use the
- Programmatically Displaying Task Flows in the ADF UI Shell [11.1.1.2] 26-DEC-2009
- This is a ready-built version of the UI Shell demo application that you can build yourself by following the step-by-step tutorial Oracle User Interface Shell. It illustrates various programmatic ways to open a task flow in the ADF UI Shell. Try the demo by running the
First.jspxpage. Each of the links in the "Choose your activity" area open a separate task flow in a tab in the UI shell. Clicking a second time on a link will activate an existing task flow tab if it already exists, rather than opening a second instance of the same task flow. TheSecond.jspxpage (to which you can navigate by clicking on the "Second" tab) illustrates menu items under the "Action" menu that each opens a distinct task flow. In this case, clicking a second time on a given menu item will open additional instances of the same task flow in the shell if one/some happen to already be open. It also illustrates toolbar icons that perform shell functions. The [1] icon opens the same task flow as the first menu item. The [2] icon marks the current tab as being "dirty". If you try to close a dirty tab, you'll see a warning dialog. The [3] icon marks a tab as not-dirty. TheThird.jspxpage illustrates opening task flows as the only content in the shell (i.e. no tabs). It also shows that a button in one task flow can open a taskflow in the shell.
- This is a ready-built version of the UI Shell demo application that you can build yourself by following the step-by-step tutorial Oracle User Interface Shell. It illustrates various programmatic ways to open a task flow in the ADF UI Shell. Try the demo by running the
- Simple UIX Pages Showing Two Techniques to Cause Query to Be Re-Executed to Refresh Data
- After writing the Why Isn't Refreshing the Browser Page Enough to Refresh the Data Displayed? article, this workspace illustrates two of the techniques described thereinusing two different ADF datapages showing the DEPT table in a UIX page. One overrides the prepareModel() method to force the underlying view object query to be re-executed on each page render. The other illustrates how to offer the user a (Refresh Data) button that let's them refresh the data by re-executing the query on-demand. The latter uses an onRefreshData() method in the related data action class to re-execute the query.
- Auto-Enabling Commit and Rollback Buttons When Any Change in an Editable Table is Made [10.1.3.4] 10-DEC-2008
- Since declarative PPR based on UI components id's in an editable table does not work in 10.1.3, this example illustrates the small bit of backing bean code (in the
onDeptnoDnameOrLocValueChange()method of the Departments backing bean) that is necessary to make the AutoSubmit=true inputText fields in the editable table automatically enable the Commit and Rollback buttons as soon as the first value is changed in the table. The page includes normal declarative PPR (via thepartialTriggersattribute) that causes a click on the (Create) button or the (Delete) button to enable the same two buttons. The expression used in thedisabledattribute is not the default one dropped by the design time because it wasn't working for me to enable the button when only a delete had been performed. This EL expression referencing the transactionDirty attribute seemed to work more reliably.
- Since declarative PPR based on UI components id's in an editable table does not work in 10.1.3, this example illustrates the small bit of backing bean code (in the
- Set Deleted Flag Instead of Actually Deleting a Row
- Sometimes when the user deletes a row, you don't actually want to physically remove the row from the table, but rather just mark a "DELETED" column to have a value like "Y" instead. This example shows how implement this by overriding the entity object's remove() method to set a "Deleted" flag before removing the row, and then overriding the entity's doDML() method to change a DML_DELETE operation into a DML_UPDATE operation instead. The example includes a SQL script to ALTER the standard EMP table to include a DELETED column.
- 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
inputFilecomponent and the backing bean logic to handle inserting the contents of the uploaded file into a BLOB column in the database. Run theCreateTables.sqlscript to drop and create the simpleUPLOADED_FILEStable. Then, run theUploadFileToBlob.jspxpage. Note that the page uses theaf:formcontainer with itsusesUploadattribute set totrue. Also notice that theinputFilecontrol is bound to the backing bean property namedfileInputComponent, allowing the backing bean to reference the UI component programmatically. ThevalueChangeListeneron theinputFileis mapped via EL to theonFileUploaded()method in the backing bean. That method accesses theExampleModuleclient interface of theExampleModuleapplication module, and invokes thesaveUploadedFile()method on it. It passes in the file name, and aBlobDomainclass representing the contents of the uploaded file. The (Upload File) button'sactionproperty is mapped via EL to theonUploadFileButtonClicked()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.
- 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
- 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
inputFilecomponent and the backing bean logic to handle inserting the contents of the uploaded file into a CLOB column in the database. Run theCreateTables.sqlscript to drop and create the simpleUPLOADED_FILEStable. Then, run theUploadFileToClob.jspxpage. Note that the page uses theaf:formcontainer with itsusesUploadattribute set totrue. Also notice that theinputFilecontrol is bound to the backing bean property namedfileInputComponent, allowing the backing bean to reference the UI component programmatically. ThevalueChangeListeneron theinputFileis mapped via EL to theonFileUploaded()method in the backing bean. That method accesses theExampleModuleclient interface of theExampleModuleapplication module, and invokes thesaveUploadedFile()method on it. It passes in the file name, and aClobDomainclass representing the contents of the uploaded file. The (Upload File) button'sactionproperty is mapped via EL to theonUploadFileButtonClicked()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.
- 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
- Upload Text File and Image Example
- Illustrates a simple, no-code-required example of how to support file upload in a JSP page and save both text documents and images into the database. Relies on using the Oracle Intermedia database datatype
ORDSYS.ORDDOCandORDSYS.ORDIMAGEand their corresponding ADF Business Components domains that do the right thing to handle working with them.
- Illustrates a simple, no-code-required example of how to support file upload in a JSP page and save both text documents and images into the database. Relies on using the Oracle Intermedia database datatype
- Use AutoRefresh VO in Shared AM with Optimized Polling to Show Latest Data in a Table [11.1.1.2] 26-DEC-2009
- This example illustrates how to use an Auto-Refresh view object in a shared application module to display the latest database changes in a table without eagerly requerying the view object. The
DeptViewview object has itsAutoRefreshproperty set totrueand theModelproject defines a shared application module instance namedAppModuleon the Business Components > Application Module Instances panel of the project properties. TheAppModuleDataControlentry in thedataControlUsagessection of theDataBindings.cpxfile in theViewControllerproject has been configured to use theAppModuleSharedconfiguration so that the UI works with a shared application module instance. As an optimization, theDeptViewview object overrides theprocessDatabaseChangeNotification()method to keep track of theSystem.currentTimeMillis()in a local member field. The view object'sgetLastRequery()is exposed on the client interface and is accessed by theDepartmentPagebacking bean's via a method action binding. That bean'sonPollTimerExpired()method only bothers to add the table UI component as a partial target if the time the view object was last requeried is greater than the time the table was last PPR'd (which it tracks in a viewScope attribute). To try the demo, run theDepartments.jspxpage. If you'd like try accessing the same page from several different browsers (e.g. Firefox, Internet Explorer, Chrome) to simulate multiple, distinct user sessions. In SQL Plus (or the JDeveloper SQL Developer worksheet window) try insert, updating, or deleting rows in theDEPTtable and committing the changes. Sometime in the next 15 seconds, the different browser user's should update to reflect the changes automatically.
- This example illustrates how to use an Auto-Refresh view object in a shared application module to display the latest database changes in a table without eagerly requerying the view object. The
- Validating Exactly One Detail Row of a Given Type [11.1.1.1, Custom schema] 04-NOV-2009
- This example illustrates two techniques for validating that a parent entity contains exactly one composed child entity of a given type. Start by running the
CreateTables.sqlscript to create theEMAIL_MESSAGEandEMAIL_MESSAGE_RECIPIENTStables. The example is a simple "Create an Email" application that allows you to create a new email message and add one or more recipients. Each recipient is of a particular RecipientType (P=Primary,C=CC,B=BCC). The rule being enforced is that there must be exactly one recipient of type "Primary". The validation is performed by an entity-level Script Expression validator on the parentEmailentity object. This validator uses Groovy code to work with a view accessor namedValidateOnePrimarywhich is of typeEmailRecipientsViewand has the design-time-applied view criteria namedPrimaryRecipient(criteria mode "Both") applied to it. This view criteria filters based on theMessageIdand theRecipientType='P'. The view accessor is configured to pass the value of the currentEmailentity'sIdattribute as the value of the view criteria'sVarMessageIdbind variable. Notice that the script validator allows multiple error messages to be defined. The validator's Groovy script executes the view accessor's query, raises one error usingadf.error.raise(*MESSAGE_KEY*)if there are no rows returned and another error if more than one row is returned. If the email and its recipients validate successfully, then they are saved to the tables, but note that no real email is sent anywhere. The default expression for theEmailRecipient.RecipientTypeattribute uses an alternative approach to the view accessor in order to conditionally assign the default recipient type for a newly createdEmailRecipiententity. The default expression isEmail.Recipients.count("RecipientType == 'P' ? 1 : null") == 0 ? 'P' : 'C'which accesses the parent email message using the reverse association accessor namedEmailthen accesses its rowset of recipients by references that email entity'sRecipientsassociation accessor attribute. Since the value of that expression is aRowSetwe can use one of the built-in rowset, in-memory aggregation functions to calculate thecountof the childEmailRecipiententity instances which have aRecipientTypeequal toP. Thecount()rowset aggregate function evaluates its String argument as a Groovy expression in the context of each row in the rowset over which it iterates. If the expression evaluates to null, then the count does not include that row. If the expression evaluates to non-null, then that row is counted. Finally, it uses a ternary expression so that if the count ofEmailRecipientinstances havingRecipientTypeequals toPis zero, then it returns the default value ofP, otherwise it returns the default value ofCto represent a recipient being copied on the mail. TheEmailentity object includes theMessageTextattribute of typeClobDomain, and both theEmail.SenderEmailandEmailRecipient.RecipientEmailAddressattributes use a custom domain typeEmailAddresswhich validates the format of an email address. TheNewMailMessage.jsffpage fragment uses the special<f:converter converterId="oracle.genericDomain"/>component to enable JSF to work properly with these three domain-valued attributes. TheMailServerapplication module defines the custom methodcreateNewMailAndPrimaryRecipient()which creates a new email message and the first email recipient row. The method is exposed on the client interface so that the default method call activity of thecreate-new-emailbounded task flow can invoke it declaratively to prepare the service layer for the creation of a new email. TheCustomViewObjectImplclass implement a generic feature to conditionally have rows in a view object's default rowset be inserted at the end. For view objects using this framework extension class as their base class, the feature "kicks in" if the VO has the "InsertRowsAtEnd" custom property set to some non-null value like "true". TheEmailRecipientsViewin the example uses this framework extension class as its base class and has this custom property set. To run the example, run theTestPage.jspx. You'll need to login as either useruseroneorusertwo, both of whose password iswelcome1. Click on the button to create an "email" and then click (Send) to test the validation.
- This example illustrates two techniques for validating that a parent entity contains exactly one composed child entity of a given type. Start by running the
- Adding a Dynamic 'Valid' Attribute to View Objects [10.1.3]
- This example illustrates an framework extension approach for adding a dynamic attribute named
Validto any view object whose value returns true if the primary entity usage in the row is valid, or false if it is invalid. TheCustomViewObjectImplclass adds the dynamic attribute in its overriddencreate()method. TheCustomViewRowImplclass overrides thegetAttributeInternal()method to return the desired value for the dynamic attribute. TheEmpentity 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. Theuntitled1.jspxpage in the ViewController project has a ADF Faces table and references the dynamicValidattribute to highlight invalid rows in yellow using some appropriate EL expressions in theinlineStyleattribute of the fields in the table. Theuntitled1PageDef.xmlfile had to be hand-modified to include the dynamicValidattribute in the AttrList of theEmpViewtable binding so that the EL expression used above of#{row.Valid}would be resolvable. And finally, theUntitled1PageControllerclass is registered as a custom page controller for theuntitled1.jspxpage (by setting theControllerClassattribute at the root of the page def XML document. This custom controller overrides the default way that thevalidateModelUpdates()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.
- This example illustrates an framework extension approach for adding a dynamic attribute named
- 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.sqlscript that creates aUSER_INFOtable withUSERNAMEandPASSWORDcolumns. As a trivial example of a entity object String-valued attribute stored in encoded format, the correspondingUserInfoentity object assumes that itsPasswordshould 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 aCustomEntityImplframework extension class, which theUserInfoentity 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 namedEncodeValue, which theUserInfoentity'sPasswordattribute 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.
- 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
- 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
INlist in a view object's query. For example, imagine that you want aDeptViewview object to feature aWHERElikeDEPTNO IN (:TheDeptNo)but you need theINclause 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 theCreateTypeAndFunction.sqlscript to create theNUM_TABLEtype and theIN_NUMBER_LIST()function. The function accepts a comma-separate string argument and returns aNUM_TABLEas its result. This allows theCommaSeparatedListOfDeptnobind variable in the example'sDeptViewview object to be of type String. The view object'sWHEREclause looks likeDEPTNO IN (SELECT * FROM TABLE( CAST ( in_number_list(:CommaSeparatedListOfDeptno) as num_table) ) ). Run theAppModulein the tester can try entering values like "10" and "10,40" for the bind variable to see it in action.
- This example illustrates a simpler way to achive a variable
- View Link Accessor Driving Details from a Parameterized Table Function [10.1.3]
- This example contains two read-only view objects in its
Modelproject, one namedMasterViewand the other namedListBasedOnTableFunction. The former is a simple SELECT from DUAL that unions two rows of dummy data. The first row has the value "D" for itsLIST_TYPEcolumn, and the second row has the value "E". TheListForMasterRowview link defines a link between the master viewsListTypeattribute 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". TheListBasedOnTableFunctionview object defines a named bind variableBind_ListTypethat 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 theGET_NAME_VALUE_LIST()PL/SQL function whose invocation it wraps in aTABLE()operator to treat the table-valued function result as if it were a table of data. TheCreateTypesAndFunctions.sqlscript in the Model project creates theNAME_VALUE_TYPEobject type, theNAME_VALUE_LISTtype, and theGET_NAME_VALUE_LIST()function. The function is written to return a list of (Dname,Deptno) pairs from theDEPTtable 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. TheViewControllerproject 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). TheSwingViewproject contains a simplePanel1panel with a similar Swing tree control showing the same thing.
- This example contains two read-only view objects in its
- Driving All JSF Application Menus from Single XML File [10.1.3]
- This example illustrates an XMLMenuManager bean that reads in a single XML file (using Apache Commons digester) that complies with the Menus.xsd XML Schema in the project. This XML file describes all of the levels of menus for the example application. The name of the XML file is injected as a managed property in the faces-config.xml. The application doesn't really do anything beyond showing the different levels of menus, but it was some interesting ideas I wanted to share in case it gave others some thoughts to run with to turn it into something more fully-featured. In the ViewController project, the SRDemoMenus.xml file describes the structure of the menus that you will see if you run any of the five pages in the sample. The labelKey property in the XML corresponds to the resource bundle key for showing a locale-sensitive menu label. An italian-translated message resource file is included for experimentation. Click on File, then Print to see a third-level menu.
- Using a View Object with SQLXML to Query Data from XML [10.1.3]
- This example contains a
DepartmentDataFromXMLview 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 thexmltype()constructor to treat that XML text as an XML document. Then it uses thexmlsequence()operator to treat the results ofextract()-ing the<ROWSET>/<ROW>elements from the XML document as individual rows of source data. Finally, it uses thetable()operator in combination with theextractValue()operator to retrieve the data values from each row of<ROW>fragments, breaking out aDEPTNO,DNAME, andLOCvalue 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.
- This example contains a
- Using ViewObject writeXML and JSTL XML Tag Library
- Illustrates how to use the ViewObject
writeXML()method to produce a multi-level XML message for an HR schema-based data model having Departments -> EmployeesInDepartment -> DirectReports->DirectReportJobHistory with a second detail collection under Departments of Deparments -> EmployeesJobHistory. This XML document is then set as a request attribute so that the JSTL XML library can render the multi-level information using XPath expressions. The sample contains both Struts and Model 1 examples (requires the HR schema).
- Illustrates how to use the ViewObject
- Simple JClient Panel Binding to JavaBean DataControlMethod Returning Array of Order Beans
- This demo illustrates is asimple example of a hand-written CustomerService JavaBean data control that has a single method public Order[] findAllOrdersByCustomer(Customer c). I'm just simulating the data by constructing it inside the service method. To create the panel, I dropped a button and a text field onto a JPanel in the BorderLayout-North position of the main panel, then added a JScrollPane into the BorderLayout-center position. Finally, I expanded the "Operations" node in the data control palette, expanded the findAllOrdersByCustomer method to see the "return" node, and then dropped a table for it into the JScrollPane. I added one line of code to initially bind the method result iterator rowset to null, which allowed me to avoid invoking the service method when the panel is initially displayed. Typing in values of "1" and "2" into the field and pressing (Go) cause different orders to show in the grid.
- One Page Deferred Query Example
- Shows how to use
setMaxFetchSize(0)to prevent a view object from executing before the page has a chance to capture a bind variable value from the end-user.
- Shows how to use
- Posting Multi-LevelXML Data Over HTTP to ADF Business Components
- Run the XMLPosting project (requires using IE browser for XML HTTP Posting functionality in the browser page for now). You can edit the XML message that will be posted to the server for handling by your ADF Application Module. It illustrates that you can post any number of departments and employees in the XML message. Those that are new will be inserted. Those theat are existing will be updated. If you add a Status="Terminated" attribute to an element, it will get deleted. Try updating an emp to have a salary lower than 100, the business logic encapsulated in the entity objects is triggered and errors are returned in an XML message for display by the client. Try entering a salary that is more than 1000 times the length of the employee's name. This triggers an example of an object-level validation rule that involved multiple attributes in the rule. Try adjusting salaries of one or more emps in a department such that the sum of their salaries exceed 11,000. This triggers the failure of a more complex validation rule. The demo also illustrates how, via inbound and outbound XSLT transformation (supported in the ADF readXML() and writeXML() API), the external XML format can be transformed from anything into the canonical XML format that ADF Business Compoments expects on the inbound, and vice versa on the output.