Please disable your adblock and script blockers to view this page

Search this blog

Friday, 23 May 2014

Reading html source of a webpage (url) using Oracle ADF (af:richTextEditor) & Java

This post is about a common question asked in java-

How to read page source of a website ? or how to get html source of an url?

so for that there is a simple piece of code to read html source of a webpage using it's url, and i have added  af:richTextEditor (ADF Faces component for ricj text formatting) to show html form of url source

  • I have a page with one input text to capture url entered by user, a button to fetch html source of that webpage and a af:richTextEditor to show source code in editing mode and in html mode 


  • See how to get webpage source from an url using java and save it to a html file (download a webpage ), Bind inputText and richInputText to managed bean and craete a actionListener on button to get source

  •     // Input text Binding to get URL
        private RichInputText webPageUrlBind;
        // RickInput text Binding to set Source
        private RichTextEditor richTextBind;
        public void setWebPageUrlBind(RichInputText webPageUrlBind) {
            this.webPageUrlBind = webPageUrlBind;
        }
    
        public RichInputText getWebPageUrlBind() {
            return webPageUrlBind;
        }
    
        public void setRichTextBind(RichTextEditor richTextBind) {
            this.richTextBind = richTextBind;
        }
    
        public RichTextEditor getRichTextBind() {
            return richTextBind;
        }
        /**Method to get html source of url (webpage) and set this to rickTextEditor
         * @param actionEvent
         */
        public void getSourceCodeAction(ActionEvent actionEvent) {
            URL url = null;
    
            try {
                if (webPageUrlBind.getValue() != null) {
                    // Define your URL- Get value from input text using binding
                    url = new URL(webPageUrlBind.getValue().toString());
                }
                URLConnection conn = url.openConnection();
    
                // open the stream and put it into BufferedReader
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    
                String inputLine;
                String sourceCode = "";
    
                //Save html file (HTML Source Code of given URL)
                String fileName = "D:/web-content.html";
                File file = new File(fileName);
    
                if (!file.exists()) {
                    file.createNewFile();
                }
    
                //use FileWriter to write file
                FileWriter fw = new FileWriter(file.getAbsoluteFile());
                BufferedWriter bw = new BufferedWriter(fw);
                System.out.println("Printing WebPage source on console, Please wait...\n");
                while ((inputLine = br.readLine()) != null) {
                    System.out.println(inputLine);
                    bw.write(inputLine);
                    sourceCode = sourceCode.concat(inputLine);
                }
    
                bw.close();
                br.close();
                richTextBind.setValue(sourceCode);
                AdfFacesContext.getCurrentInstance().addPartialTarget(richTextBind);
                System.out.println("\n\nYour file is save in D drive! Congratulations ");
    
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    




  • now click on button and see , here i am getting source code of this blog http://oracleadf-java.blogspot.in/


  • now switch RichTextMode to see html preview of this source, it is exactly looking like live webpage, it shows one can practice in this ADF Faces's rickTextEditor to learn html tags


  • and see in D drive of your system a file named web-content created , it contains whole source of this webpage
 Cheers - Happy Learning :)

Tuesday, 20 May 2014

Blocking row navigation in af:table , synchronize row selection with model in case of validation failure- Oracle ADF

In ADF we often work on editable af:table and when we use af:table to insert ,update or delete data, it is normal to use some validation
but problem is when some validation failure occurs on page (in af:table) ,still we can select another row and it shows as currently selected Row
this is a bit confusing for user as Row Selection of af:table is not synchronized with model or binding layer

See Problem- 
  • I have an editable table on page


  • Added a validation to check negative value in field of LocationId, now navigate to another row


  • See selected focus is on Academic, but problem is when there is validation failure, why it is showing other row as selected ? 



  • If you check in ViewObject , you will find that row with DepartmentName Human Resource is current row

ADF framework provides a property in af:table to control navigation in af:table when there is some error or validation failure- blockRowNavigationOnError
See in oracle docs about this proprty-

Valid Values: always, never, auto


Whether we want to block row navigation in case of validation failure.
This is when you select a row and do some editing inside the table or in a related form, and this editing causes some validation failures. At this time, if you click on a different row in table, we want to block you from moving to the new row.
possible values are: always, never and auto. default value is auto.

  • always means we block the row navigation
  • never means we don't block and let the row navigation happen
  • auto means the framework will make the decision



by default in af:tabel it's value is <auto>


Change it to <always> and now see behavior on page


 now if you try to select another row, it is not get selected and selected focus is on row with validation

Sample ADF Application-Download
Cheers - Happy Learning :-)

Thursday, 15 May 2014

Overriding Reset button action (QueryOperationListener) of af:query, Changing query mode, Handling QueryOperationEvent programmatically-Oracle ADF

Hello All ,
previously i had a requirement of validating af:query fields so i have found two ways to do that
see -Overriding default query listener ,field validation of af:query- Oracle ADF

now i have to set some values in af:query when user clicks on Reset button of query so to do that i have to override default QueryOperationListener in order to handle QueryOperationEvent  



Oracle docs says-

af:query- The query component provides the user the ability to perform a query based on a saved search or personalize saved searches in Oracle ADF. The component displays a search panel with various elements, each of which help the user to accomplish various tasks. 

QueryOperationListener- QueryOperationListener class. A registered queryOperationListener is invoked when the user's action results a queue and broadcast of QueryOpertionEvent on the component. For example, click the delete icon in the QuickCriteria component or click "Save", "Reset" etc buttons in Query component to perform a Query Operation.

 QueryOperationEvent-A user can perform various operations on saved searches while interacting with a query component. These actions include creating, overriding, deleting, duplicating, selecting, resetting and updating a saved search

want to read more-  
http://docs.oracle.com/cd/E17904_01/apirefs.1111/e10684/oracle/adf/view/rich/event/QueryOperationListener.html
http://jdevadf.oracle.com/adf-richclient-demo/docs/apidocs/oracle/adf/view/rich/event/QueryOperationEvent.html  

so i have created a QueryOperationListener in managed bean that communicates with QueryOperationEvent

in this method we can capture various events of af:query as reset,update
so for this use-case i have to capture reset and set desired values in query attribute (viewObject's bind variable) , here i am using Departments table of HR Schema



now see the code (i have to set Human Resource department on reset in search panel) - how to capture raised event when user clicks on Reset button of af:query


    /**Custom QueryOperationListener that hadles variois events raised by af:query
     * @param queryOperationEvent
     */
    public void deptSeacrhQueryOperationList(QueryOperationEvent queryOperationEvent) {
        //Invoke default operation listener
        invokeEL("#{bindings.DepartmentsVOCriteriaQuery.processQueryOperation}", Object.class,
                 QueryOperationEvent.class, queryOperationEvent);

        System.out.println("Query Event is-" + queryOperationEvent.getOperation().name());
        //Check that current operation is RESET
        if (queryOperationEvent.getOperation().name().equalsIgnoreCase("RESET")) {
            DCIteratorBinding iter = (DCIteratorBinding) getBindings().get("Departments1Iterator");

            ViewObjectImpl vo = (ViewObjectImpl) iter.getViewObject();
            // Setting the value of bind variable
            vo.ensureVariableManager().setVariableValue("BindDeptNm", "Human Resource");
        }
    }

to invoke Expression use this method


    /**
     * @param expr
     * @param returnType
     * @param argTypes
     * @param args
     * @return
     */
    public Object invokeMethodExpression(String expr, Class returnType, Class[] argTypes, Object[] args) {
        FacesContext fc = FacesContext.getCurrentInstance();
        ELContext elctx = fc.getELContext();
        ExpressionFactory elFactory = fc.getApplication().getExpressionFactory();
        MethodExpression methodExpr = elFactory.createMethodExpression(elctx, expr, returnType, argTypes);
        return methodExpr.invoke(elctx, args);
    }

    /**
     * @param expr
     * @param returnType
     * @param argType
     * @param argument
     * @return
     */
    public Object invokeEL(String expr, Class returnType, Class argType, Object argument) {
        return invokeMethodExpression(expr, returnType, new Class[] { argType }, new Object[] { argument });
    }

now run this page and check on click of reset button this listener is invoked and sets the value of af:query field
Default page view -on-load


 after click on Reset-


other than this reset we can handle other events of af:query (for saved search there are various events based on corresponding operations) as DELETE, UPDATE, CREATE


on clicking various button of this personalized search box we get respective operation  name in managed bean and can handle as  done for RESET operation

Changing mode of default search panel (af:query) of ADF-
this is nothing but  2 lines that changes the mode of af:query - Basic to Advanced & Advanced to Basic

so dropped a button on page to change af:query search mode and see the code of ActionListener for this


//Binding of af:query in managed bean  
  private RichQuery queryPanelDept;
    
    public void setQueryPanelDept(RichQuery queryPanelDept) {
        this.queryPanelDept = queryPanelDept;
    }
    public RichQuery getQueryPanelDept() {
        return queryPanelDept;
    }


    private String current_mode = "B";

    /**Method Action to change mode of af:query
     * @param actionEvent
     */
    public void changeModeAction(ActionEvent actionEvent) {
        if (current_mode == "B") {
            getQueryPanelDept().getValue().changeMode(QueryDescriptor.QueryMode.ADVANCED);
            current_mode = "A";
        } else if (current_mode == "A") {
            getQueryPanelDept().getValue().changeMode(QueryDescriptor.QueryMode.BASIC);
            current_mode = "B";
        }
    }

now run page and see-



Cheers - Happy learning :-) Download Sample ADF App