Overriding default query listener,field validation of af:query- Oracle ADF

Sharing is Caring

Hello All,
this post talks about a common requirement – How to perform field validation of af:query ? yes, we can do that by overriding default query listener of af:query component

What af:query is ?

Oracle Docs-af:query

“The query component provides the user the ability to perform a query based on a saved search or personalize saved searches. The component displays a search panel with various elements, each of which helps the user to accomplish various tasks.”
Follow steps to do field validation of af:query-
  • Here I am taking the example of Departments table of HR Schema
  • First, create business components for Departments table
  • Create bind variables and a view-criteria in departments view object
  • See the view criteria is applied for LocationId, ManagerId and Department Name
  • Now create a page and drop criteria with the table on the page- it will look like this
  • Next is to select af:query on the page and go to property inspector and copy the text of default query listener
    • Now create a managed bean and create a custom query listener for af:query

       

    • In this custom query listener, in this example, I am checking for negative Location Id and Manager Id, if there are any negative values, the custom method will show a message otherwise default queryListener will be executed
    • We can get af:query’s components value using 2 methods
      First One  – Using Bind Variable (getNamedWhereClauseParam)
      Second One – Using QueryDescriptor and ConjunctionCriterion
    • I’m going to explain both methods – see the code of custom query listener using the first method, two generic methods will be used in this process to invoke expression language and to get BindingContainer of the current context

    /**Method to invoke EL Expression
     * @param el
     * @param paramTypes
     * @param params
     * @return
     */
    public static Object invokeEL(String el, Class[] paramTypes, Object[] params) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ELContext elContext = facesContext.getELContext();
        ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
        MethodExpression exp = expressionFactory.createMethodExpression(elContext, el, Object.class, paramTypes);

return exp.invoke(elContext, params);
}

/**Method to get Binding Container of the current page
 * @return
 */
public BindingContainer getBindings() {
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

 

  • See the first method to get af:query components value and validate that
    /**Custome Query Listener- Using getNamedWhereClauseParam
     * @param queryEvent
     */
    public void customQueryListener(QueryEvent queryEvent) {
        String deptName = null;
        Integer locId = null;
        Integer mgrId = null;

/**Get Iterator of Table*/
DCIteratorBinding iter = (DCIteratorBinding)getBindings().get("DepartmentsView1Iterator");

/**Get ViewObject from Iterator*/
ViewObjectImpl vo = (ViewObjectImpl)iter.getViewObject();

/**Get Bind Variable's Value*/
if (vo.getNamedWhereClauseParam("LocIdBind") != null) {
locId = Integer.parseInt(vo.getNamedWhereClauseParam("LocIdBind").toString());
}
if (vo.getNamedWhereClauseParam("MgrIdBind") != null) {
mgrId = Integer.parseInt(vo.getNamedWhereClauseParam("MgrIdBind").toString());
}
if (vo.getNamedWhereClauseParam("DeptNmBind") != null) {
deptName = vo.getNamedWhereClauseParam("DeptNmBind").toString();
}

/**Check for Negative values*/
if ((locId != null && locId < 0) || (mgrId != null && mgrId < 0)) {
FacesMessage msg = new FacesMessage("Id Value can not be negative");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(null, msg);
} else {
/**Execute default query listener with help of invokeEL method*/

invokeEL("#{bindings.DepartmentsViewCriteriaQuery.processQuery}", new Class[] { QueryEvent.class },
new Object[] { queryEvent });
}
}

 

  • And Second Method using QueryDescriptor is-
    /**Custom Query Listener-Using QueryDescriptor
     * @param queryEvent
     */
    public void customqueryProcess(QueryEvent queryEvent) {
        String deptName = null;
        Integer locId = null;
        Integer mgrId = null;

/**Reference-Frank Nimphius Example- ADF Code Corner
 * http://www.oracle.com/technetwork/developer-tools/adf/learnmore/85-querycomponent-fieldvalidation-427197.pdf
 * */
QueryDescriptor qd = queryEvent.getDescriptor();

ConjunctionCriterion conCrit = qd.getConjunctionCriterion();
//access the list of search fields
List<Criterion> criterionList = conCrit.getCriterionList();
//iterate over the attributes to find FromDate and ToDate
for (Criterion criterion : criterionList) {
AttributeDescriptor attrDescriptor = ((AttributeCriterion)criterion).getAttribute();

if (attrDescriptor.getName().equalsIgnoreCase("DepartmentName")) {
deptName = (String)((AttributeCriterion)criterion).getValues().get(0);

} else {
if (attrDescriptor.getName().equalsIgnoreCase("LocationId")) {
locId = (Integer)((AttributeCriterion)criterion).getValues().get(0);

}
}
if (attrDescriptor.getName().equalsIgnoreCase("ManagerId")) {
mgrId = (Integer)((AttributeCriterion)criterion).getValues().get(0);

}
}
if ((locId != null && locId < 0) || (mgrId != null && mgrId < 0)) {
FacesMessage msg = new FacesMessage("Id Value can not be negative");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(null, msg);
} else {
/**Process default query listener*/
invokeEL("#{bindings.DepartmentsViewCriteriaQuery.processQuery}", new Class[] { QueryEvent.class },
new Object[] { queryEvent });
}
}

 

  • Now Run your application and check it for negative values
validation of af:query
Sample ADF Application- Download
Cheers 🙂 Happy Learning

 

Related Posts

An Oracle ACE, Blogger, Reviewer, Technical Lead working on Oracle ADF

4 thoughts on “Overriding default query listener,field validation of af:query- Oracle ADF”

  1. Very good this post and very useful.

    In the criteria for the item type to date between option,
    simply select the indices of them as 0 and 1 for the name of the desired field.

    if (attrDescriptor.getName().equalsIgnoreCase("MyDateFieldName")) {
    beginDate =(Date)((AttributeCriterion)criterion).getValues().get(0);
    endDate =(Date)((AttributeCriterion)criterion).getValues().get(1);
    }

Leave a Reply

Your email address will not be published. Required fields are marked *