Friday, May 15, 2015

Customizing af:query saved search

The below are some of the code pieces useful when customizing or overriding the af:query panel. In addition to that if you have MDS enabled for your ADF application, these saved searches CREATED or UPDATED programmatically will also be persisted to MDS.

Code to access the base query descriptor:
  private QueryDescriptor getBaseQueryDescriptor(){
    QueryDescriptor qdBase = null;
    List<QueryDescriptor> list = getQueryModel().getModel().getSystemQueries();
    for(QueryDescriptor qd : list){
      if(<VIEWCRITERIA_NAME_inVO>.equalsIgnoreCase(qd.getName())){
        System.out.println("qd name:: "+ qd.getName());
        qdBase= qd;
        break;
      }
    }
 
    return qdBase;
  }

Code to access the base viewcriteria from the criteria query:
      private ViewCriteria getViewCriteria(DCBindingContainer bc,
                QueryDescriptor qd) {
               
       Object execBinding =
         bc.findExecutableBinding("<VIEWCRITERIAQUERY_NAME_inPageDef>");   //VIEWCRITERIA_QUERY_NAME as present in the pagedef
      ViewCriteria vc =
       JUSearchBindingCustomizer.getViewCriteria((DCBindingContainer)execBinding, qd.getName());
      return vc;
     

      }

Code to create  a query descriptor from the query model programmatically:
This is same as creating a save search in UI from af:query panel. Of course one needs have MDS enabled for the application so that saved searches will be persisted per user.

private void methodCreateDescriptor(ActionEvent x){
 QueryModel qm = getQueryModel().getModel(); //create a managed bean binding for the af:query
 QueryDescriptor qdBase = getBaseQueryDescriptor(); //get the base query descriptor
  QueryDescriptor newQd =  qm.create(name, qdBase); //creates a new descriptor

      Map<String, Object> uiHints = new HashMap<String, Object>(10);
      uiHints.put(QueryDescriptor.UIHINT_MODE, QueryDescriptor.QueryMode.BASIC);
      uiHints.put((QueryDescriptor.UIHINT_NAME), name);
    //results table af:table                                                                                  
    uiHints.put(QueryDescriptor.UIHINT_RESULTS_COMPONENT_ID, "::pc1:t2");
      uiHints.put(QueryDescriptor.UIHINT_SAVE_RESULTS_LAYOUT, Boolean.TRUE);
      uiHints.put(QueryDescriptor.UIHINT_SHOW_IN_LIST, Boolean.TRUE);
//setDefault and autoExecute are check boxes in UI.
      uiHints.put(QueryDescriptor.UIHINT_DEFAULT, setDefault);
      uiHints.put(QueryDescriptor.UIHINT_AUTO_EXECUTE, autoExecute);

   
      newQd.getUIHints().clear(); //Just to make sure the MODE is set properly.
      newQd.getUIHints().putAll(uiHints);

      /**
       * As the new   QD is already created by calling qm.create(name, qdBase)
       * Now raising UPDATE event to properly update the query hints and mode.
       */
      QueryOperationEvent event_mode_change = new QueryOperationEvent(this.getQueryModel(),QueryOperationEvent.Operation.UPDATE, newQd, uiHints);
      invokeMethodExpression("#{bindings.AuditViewCriteriaQuery.processQueryOperation}", Object.class,
                             new Class[]{QueryOperationEvent.class}, new Object[]{event_mode_change});
      qm.setCurrentDescriptor(newQd); //If you want to set the new QD as current descriptor
//Do the above step only after invoking the above UPDATE event, otherwise the mode will not be set properly.
}

Override queryListener of af:query

public void processCustomQuery(QueryEvent queryEvent) {
//Do you code here
  invokeMethodExpression("#{bindings.AuditViewCriteriaQuery.processQuery}", Object.class,

                             new Class[]{QueryEvent.class}, new Object[]{queryEvent});
}

Override queryOperationListener of af:query
 public void processCustomQueryOperation(QueryOperationEvent queryOperationEvent) {
QueryDescriptor qd = queryOperationEvent.getDescriptor();
//Your code here
    invokeMethodExpression("#{bindings.AuditViewCriteriaQuery.processQueryOperation}", Object.class,
                           new Class[]{QueryOperationEvent.class}, new Object[]{queryOperationEvent});
}
 
invokeMethodExpression method
  public Object invokeMethodExpression(String expr, Class returnType, Class[]  argClasses, Object[] arguments){
        FacesContext fc = FacesContext.getCurrentInstance();
        ELContext elc = fc.getELContext();
        ExpressionFactory exprFactory = fc.getApplication().getExpressionFactory();
        MethodExpression methodExpr = exprFactory.createMethodExpression(elc,expr,returnType,argClasses);  
        return methodExpr.invoke(elc,arguments);
       }

Note: Code base is on 11.1.1.7