Extending POJO based Bean Data Control to add the features you wanted (such as Named Criteria and af:query) !
I blogged about bean data control and pagination support a while back http://www.jobinesh.com/2011/03/what-you-may-need-to-know-about.html. Look like it is time to revisit this stuff to share few more interesting things on extending the features offered. While talking to some developers I realized that POJO based bean data control need few more extra fittings to make it more developer friendly ;) . For example out of the box support for af:query (i.e af:query backed up by named criteria that you may find for JPA based Bean Data Control) is one feature that is still missing. In this post, I'm sharing a sample which uses an enhanced custom DataControlHandler to help you with out of the box query component and pagination support that you may otherwise find missing.
The sample that I'm sharing here is built using 12.1.2.0.0. As 12 C has a lot of improvements on bean data control implementation, the custom DataControlHandler used in this sample will not work on previous JDeveloper/ADF versions (as it uses the new APIs from 12C). With this sample, I just wanted to show you that most of the pieces that you may see in the framework are extendable, and you can add the features your own. Try it out if you love fun. Ah yes, you may need to spend some time on understanding their working though.
Download
You can download the sample workspace from here. Take a look at the ExtndPOJOModel project to get a feel of the framework extension classes that we are talking in the following section.
[ Runs with Oracle JDeveloper 12.1.2.0.0 or higher.]
A glance at the implementation
This sample uses following framework extension classes. These classes are available in ExtndPOJOModel project which is part of the sample work space that I shared above.
The extended data control handler that you find in this sample (SimpleBeanDCDataFilterHandler.java) offers the pagination and query support for your POJO bean data control even if the data collection returned by your Java class is not based on JPA entities. The SimpleBeanDCDataFilterHandler is built by extending oracle.adf.model.adapter.bean.DataFilterHandler. It overrides the invoke(RowContext rowCtx, String name, DataFilter filter) method to return a custom SimpleBeanDataCollection. The SimpleBeanDataCollection is extended from oracle.adf.model.adapter.bean.provider.BeanDataCollection. The SimpleBeanDataCollection is the real work horse here, which invokes appropriate method in your Java Bean during the page life cycle phases as appropriate. The class SimpleBeanDataCollection expects a method of following signature in your Java service class(the one you selected for building data control)
public Object queryByRange(SimpleSearchCriteria searchCriteria). This method will be triggered when user queries using af:query component and also during paginated fetch facilitated by the binding layer. For a Java Bean Data Control that returns POJO collection, there is no automated 'query' thing involved and no other back magic). So if you use the extension given in this post, the queryByRange(SimpleSearchCriteria ) method in your Java class should have logic to return the collection requested by the client. You can get the search conditions and paging parameters from SimpleSearchCriteria parameter of this method. On a related note, framework will do an in-memory filtering for you if the named criteria's (that you defined in you POJO model's xml definition, e.g Departments.xml) query mode is set to In
-Memory or Both. That said, however, in-memory filtering may not be a right choice if you have large number of elements. As I said earliear, these are extensible pieces, feel free to add more features as you need.
Is there any manual labor involved to use custom SimpleBeanDCDataFilterHandler ?
Answer is Yes, You may not see visual editor support to leverage the offerings from SimpleBeanDCDataFilterHandler. The following are the steps that you may want to do manually:
Update on 9 July 2014 : Please note that later built JDeveloper extension for the custom Bean DC discussed in this post, which may help you to leverage visual editor support for building VC http://www.jobinesh.com/2014/07/java-bean-dc-extension-for-jdeveloper.html
You are done. If you run the page, you may get a nice search page powered by af:query on the front end and your own handler on the back end.
The sample that I'm sharing here is built using 12.1.2.0.0. As 12 C has a lot of improvements on bean data control implementation, the custom DataControlHandler used in this sample will not work on previous JDeveloper/ADF versions (as it uses the new APIs from 12C). With this sample, I just wanted to show you that most of the pieces that you may see in the framework are extendable, and you can add the features your own. Try it out if you love fun. Ah yes, you may need to spend some time on understanding their working though.
Download
You can download the sample workspace from here. Take a look at the ExtndPOJOModel project to get a feel of the framework extension classes that we are talking in the following section.
[ Runs with Oracle JDeveloper 12.1.2.0.0 or higher.]
A glance at the implementation
This sample uses following framework extension classes. These classes are available in ExtndPOJOModel project which is part of the sample work space that I shared above.
- SimpleBeanDCDataFilterHandler extends DataFilterHandler : This is the custom data control handler class used in this sample in order to enable query and pagination support for a bean data control. This class is hooked to the ADF run time by pointing DataControlHandler entry that you see for bean-definition entry (in DataControls.dcx) to this class.
- SimpleBeanDataCollection
extends BeanDataCollection : The SimpleBeanDCDataFilterHandler uses this class as a data structure to return the collection of Java bean requested by the client. In fact this class does more work than you expect, its the real 'work horse' here which reads collection from your Java service class and issues appropriate queries to it whenever client ask for data. - SimpleSearchCriteria : A custom data structure used by the SimpleBeanDataCollection to pass the search conditions to your Java Bean.
- SimpleCriteriaItem : Search conditions are represented by this class. SimpleSearchCriteria holds collection of SimpleCriteriaItem.
The extended data control handler that you find in this sample (SimpleBeanDCDataFilterHandler.java) offers the pagination and query support for your POJO bean data control even if the data collection returned by your Java class is not based on JPA entities. The SimpleBeanDCDataFilterHandler is built by extending oracle.adf.model.adapter.bean.DataFilterHandler. It overrides the invoke(RowContext rowCtx, String name, DataFilter filter) method to return a custom SimpleBeanDataCollection. The SimpleBeanDataCollection is extended from oracle.adf.model.adapter.bean.provider.BeanDataCollection. The SimpleBeanDataCollection is the real work horse here, which invokes appropriate method in your Java Bean during the page life cycle phases as appropriate. The class SimpleBeanDataCollection expects a method of following signature in your Java service class(the one you selected for building data control)
public Object queryByRange(SimpleSearchCriteria searchCriteria). This method will be triggered when user queries using af:query component and also during paginated fetch facilitated by the binding layer. For a Java Bean Data Control that returns POJO collection, there is no automated 'query' thing involved and no other back magic). So if you use the extension given in this post, the queryByRange(SimpleSearchCriteria ) method in your Java class should have logic to return the collection requested by the client. You can get the search conditions and paging parameters from SimpleSearchCriteria parameter of this method. On a related note, framework will do an in-memory filtering for you if the named criteria's (that you defined in you POJO model's xml definition, e.g Departments.xml) query mode is set to In
-Memory or Both. That said, however, in-memory filtering may not be a right choice if you have large number of elements. As I said earliear, these are extensible pieces, feel free to add more features as you need.
Is there any manual labor involved to use custom SimpleBeanDCDataFilterHandler ?
Answer is Yes, You may not see visual editor support to leverage the offerings from SimpleBeanDCDataFilterHandler. The following are the steps that you may want to do manually:
- Build you POJO based model, then create data control by selecting appropriate Java service class
- After creating data control, open DataControls.dcx and update the value for DataControlHandler in bean-definition tag as shown below.
<bean-definition BeanClass="pojo.model.extension.ExtendedJavaService" DataControlHandler="com.jobinesh.framework.extension.SimpleBeanDCDataFilterHandler" AccessMode="scrollable" EagerPersist="false" xmlns="http://xmlns.oracle.com/adfm/adapter/bean"/>
- Open the Java service class that you selected for building data control and add the following method:
public Object queryByRange(SimpleSearchCriteria searchCriteria) { ... }
This method will have logic to return appropriate collection by reading search conditions and paging parameters passed through SimpleSearchCriteria parameter.- Now let us add a view criteria to the appropriate Java bean sparse XML. Edit the collection in the data control panel to create XML file for the Java bean used in the collection. As there is no visual editor support, you may need to manually add a view criteria in to the Java bean sparse XML and mark all attributes used in the view view criteria as Queriable, by setting IsQueriable="true". Take a look at Department.xml in the sample work space where you may see the code snippet that I added manually(Shhh, I copied this from a JPA based bean data control). Relevant part is here:
<ViewCriteria Name="DepartmentCriteria" ViewObjectName="pojo.model.extension.Department" Conjunction="AND" Mode="3"> <Properties> <CustomProperties> <Property Name="displayOperators" Value="InAdvancedMode"/> <Property Name="autoExecute" Value="false"/> <Property Name="allowConjunctionOverride" Value="true"/> <Property Name="showInList" Value="true"/> <Property Name="mode" Value="Basic"/> </CustomProperties> </Properties> <ViewCriteriaRow Name="DepartmentCriteria_row_0" UpperColumns="1"> <ViewCriteriaItem Name="DepartmentCriteria_DepartmentCriteria_row_0_departmentId" ViewAttribute="departmentId" Operator="=" Conjunction="AND" Required="Optional"/> <ViewCriteriaItem Name="DepartmentCriteria_DepartmentCriteria_row_0_departmentName" ViewAttribute="departmentName" Operator="STARTSWITH" Conjunction="AND" Required="Optional"/> <ViewCriteriaItem Name="DepartmentCriteria_DepartmentCriteria_row_0_locationId" ViewAttribute="locationId" Operator="=" Conjunction="AND" Required="Optional"/> </ViewCriteriaRow> </ViewCriteria>
Update on 9 July 2014 : Please note that later built JDeveloper extension for the custom Bean DC discussed in this post, which may help you to leverage visual editor support for building VC http://www.jobinesh.com/2014/07/java-bean-dc-extension-for-jdeveloper.html
- To build a search page, go to view controller project , create a page. Then drop the appropriate collection from the data control to the page as table component. There is no visual editor support for building query component for our data control with custom handler, so let us do it manually. Open page definition editor, select source tab and add the search region binding as appropriate. An example is here(Short cut is copy this entry from any of your pages where you have af:query with binding support, and make appropriate changes):
<executables> ... <searchRegion Criteria="DepartmentCriteria" Customizer="oracle.jbo.uicli.binding.JUSearchBindingCustomizer" Binds="departmentsFindAllIterator" id="DepartmentCriteriaQuery"/> </executables>
- Move back to the jsf source, and add af:query component with binding to the the search region binding that we created in last step.
<af:query id="qryId1" headerText="Search" disclosed="true" value="#{bindings.DepartmentCriteriaQuery.queryDescriptor}" model="#{bindings.DepartmentCriteriaQuery.queryModel}" queryListener="#{bindings.DepartmentCriteriaQuery.processQuery}" queryOperationListener="#{bindings.DepartmentCriteriaQuery.processQueryOperation}" resultComponentId="::t1"/>
You are done. If you run the page, you may get a nice search page powered by af:query on the front end and your own handler on the back end.
I created a simple data control that returns a list of POGO objects. The page retrieves the list once and displays the data but I Can't seem to get it to refresh when the backing data changes. Calling Execute on the list binding does nothing. What is the best way to force the datacontrol to refresh?
ReplyDeleteYour download link doesn't work for me (using firefox)
ReplyDeleteSecure Connection Failed
An error occurred during a connection to drive.google.com. SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long)
The download link is working. You should try another network before posting here.
ReplyDeleteThis post is very inspiring to me and it's very nice. I expect more info about this title and Thanks for your sharing...!
ReplyDeleteSpark Training in Chennai
Spark Training
Embedded System Course Chennai
Linux Training in Chennai
Social Media Marketing Courses in Chennai
Pega Training in Chennai
Primavera Training in Chennai
Unix Training in Chennai
ReplyDeleteGreat info. The content you wrote is very interesting to read. This will loved by all age groups.
ReactJS Training in Chennai
ReactJS Training
ReactJS course
ccna Training in Chennai
Salesforce Training in Chennai
Angularjs Training in Chennai
This comment has been removed by the author.
ReplyDeleteNice idea,keep sharing your ideas with us.i hope this information's will be helpful for the new learners.
ReplyDeleteSoftware Testing Training in Chennai
software testing course in chennai
JAVA Training in Chennai
Python Training in Chennai
Big data training in chennai
Selenium Training in Chennai
Software Testing Training in Chennai
Software testing training in OMR
I wondered upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and I hope you post again soon.
ReplyDeletePHP Training in Chennai
PHP Course in Chennai
Big Data Analytics Courses in Chennai
Hadoop Course in Chennai
Advanced Java Training in Chennai
German Courses in Chennai
German Language Course in Chennai
PHP Training in Adyar