Please disable your adblock and script blockers to view this page

Search this blog

Friday, 10 January 2014

Oracle ADF Tutorial- How to learn Oracle ADF from scratch ?


Hello All

If you are new to ADF and want to learn this framework then you must be aware of good sources of Oracle ADF tutorials




You must refer a good book to clear your basics as Oracle ADF Real World Developer’s Guide


and start with Oracle ADF Insider videos after that refer Oracle JDeveloper 12c (12.1.3) Tutorials
After this start referring Oracle ADF Blogs for advance development and check all the sample applications provided there, Here you can find some of the best blogs
In case of any problem any issue related to ADF, Ask in OTN forum
Use social media to get new updates about product and blogs




Cheers :-) Happy Learning

Friday, 3 January 2014

Identifying Modified/newely added row in af:table, get all modified rows of viewobject in bean

Hello All,
first of all, a very Happy new year to everyone, learn more and more ADF


this tutorial is about a requirement of showing modified rows on page
Suppose if there is lot of data in af:table and user is modifying some rows then it must reflected immediately on page that which rows are modified for more clarity

Andrejus has also posted about it in 2010
http://andrejusb.blogspot.in/2010/04/changed-row-highlighting-in-oracle-adf.html

But this post talks about two requirements-
  1. Want to highlight modified rows only on page
  2. Want to get modified rows in managed bean
First One could be achieved without writing a single line of code only using expression, a row in table or view object has four state-



  • New
  • Modified
  • Un-Modified
  • Initialized


/* this expression returns state of current row in collection such as table or treeTable*/
#{row.row.entities[0].entityState} 

/*here row is reference variable of collection, this expression returns an int value if it is 
 2-Modified
 0-New
 1-Unmodified
-1-Initialized
*/

  • I'm using Departments table of HR Schema to implement this sample app
  • after business components configuration ,Drop departments VO from data control on page as af:table
  • Now to check row status , i have written following expression in inline style of af:column of af:table, so that it can check state of all rows of table 

  • #{row.row.entities[0].entityState==2 ? 'background-color:orange' : row.row.entities[0].entityState==0 ? 'background-color:darkgreen' : ''} 
    

  • Now Run your page and change any value of table
       After Updating Values in Row- see modified rows are highlighted
  •  Now you are done with first requirement , if we talk about second one, in case you want to get all modified rows in managed bean to perform some operation
  • To achieve this i have used a transient attribute in Departments view Object to store state of each row
  • Now in RowImpl of departments viewobject i have to write some code to get current state of Row, see the getter method of transient attribute in RowImpl

  •     /**
         * Gets the attribute value for the calculated attribute CheckRowStatus.
         * @return the CheckRowStatus
         */
        public Integer getCheckRowStatus() {
            byte entityState = this.getEntity(0).getEntityState();
            return new Integer(entityState);
    
            // return (Integer) getAttributeInternal(CHECKROWSTATUS);
        }
    

  • Now i have placed a button on page to get all modified rows and show a message on page through managed bean
  • See the method written in ApplicationModuleImpl class and then exposed to client to be used in managed bean action event

  •     /**Method to get all modified rows and store corresponding Department Name in an ArrayList
         * @return
         */
        public ArrayList<String> getModifiedRows() {
            ArrayList<String> deptNm = new ArrayList<String>();
            ViewObject deptVo = this.getDepartmentsView1();
            RowSetIterator deptIter = deptVo.createRowSetIterator(null);
            while (deptIter.hasNext()) {
                Row nextRow = deptIter.next();
                if (nextRow.getAttribute("CheckRowStatus") != null) {
                    Integer rowStatus = (Integer)nextRow.getAttribute("CheckRowStatus");
                    if (rowStatus == 2) {
                        deptNm.add(nextRow.getAttribute("DepartmentName").toString());
                    }
                }
            }
            return deptNm;
    
        }
    

  • Now call this method in managed bean through Binding Layer

  •     /**Method to get BindingContainer of current page
         * @return
         */
        public BindingContainer getBindings() {
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**Method to call AM method and to show modified rows on page in FacesMessage
         * @param actionEvent
         */
        public void getModifiedRows(ActionEvent actionEvent) {
            OperationBinding ob = getBindings().getOperationBinding("getModifiedRows");
            ob.execute();
            if (ob.getResult() != null) {
                ArrayList<String> deptName = (ArrayList<String>)ob.getResult();
                StringBuilder saveMsg =
                    new StringBuilder("<html><body><b><p style='color:red'>Modified Rows in Departments table are-</p></b>");
    
                saveMsg.append("<ul>");
                for (String name : deptName) {
                    System.out.println(name);
                    saveMsg.append("<li> <b>" + name + "</b></li>");
                }
    
                saveMsg.append("</ul><br>");
                saveMsg.append("</body></html>");
                FacesMessage msg = new FacesMessage(saveMsg.toString());
                FacesContext.getCurrentInstance().addMessage(null, msg);
            }
        }
    

  • Now again run this page and change some departments then click on get modified rows, it will show currently modified rows

Cheers- Download Sample App

Friday, 27 December 2013

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


Hello All,
this post talks about a common requirement - can we apply custom validation in af:query fields ? yes , we can do that by overriding default query listener of af:query component

What af:query is ?

see- 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 help the user to accomplish various tasks."


Follow steps to apply validation on af:query-
  • Here i am taking example of Departments table of HR Schema
  • First create business components for Departments table


  • then 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 table on page- it will look like this

  • Next is to select af:query on page and go to property inspector and copy 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 is any negative values ,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 code of custom query listener using first method, two generic methods will be used in this process to invoke expression language and to get BindingContainer of 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 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

Cheers- Download Sample App Happy Learning :-)