Tuesday, January 1, 2013

Creating a Login Manager Application with GWT Designer


Creating a Login Manager Application with GWT Designer


Before you can start with the tutorial, you must install a supported version of the following:
Note: This tutorial was created in Windows XP using GWT Designer 2.3, GPE 2.3, Eclipse 3.7 & Java 1.6.
Basic steps:
  1. Set the GWT installation directory
  2. Create a GWT Java Project and the LoginManager module
  3. Create the Login Composite
  4. Create and apply CSS styles
  5. Add Event Handlers
  6. Add the Login composite to the LoginManager module
  7. Run Application in Hosted Mode
  8. Build and Deploy

1. Set the path to the GWT SDK installation directory.

If you installed the Google Plugin for Eclipse (GPE), this step is not needed (GWT Designer will just use the SDK included with the GPE). Do this only if you downloaded the stand-alone GWT SDK zip file. The path would be the directory you unzipped the GWT SDK to (the dir just above the /doc subdirectory).

  • Open the GWT Preference page, select Window > Preferences > WindowBuilder > GWT.

  • Set GWT Path

    2. Create a GWT Java Project and the LoginManager module.


  • Select File > New > Project from the Eclipse top level menu to open the new project wizard dialog. 
  • Expand WindowBuilder > GWT Designer > Model and select GWT Java Project from the list of wizards.
  • Click Next to continue.

  • Select GWT Java Project

  • Enter LoginManager as the Project name and click Next.

  • Enter Project information

  • Check the option to  Create a GWT Module.
  • Enter LoginManager as the Module name.
  • Modify the package name to com.gwt.tutorial.LoginManager
  • Click Finish.

  • Create a Module
    A LoginManager GWT project is created and configured. The LoginManager file is opened and you should see Source and Design tabs at the bottom of the LoginManager view. If you don't see the tabs, right-click on the Java class and select Open With > WindowBuilder Editor.
    Source View
    To start designing your UI using GWT Designer, click the Design tab. Below is GWT Designer's Design view. Top left corner of the LoginManager is the Components view. Below the Components view is the Properties view. In the middle is the Palette and to the right is your UI.
    Design View

    3. Create the Login Composite.

    First, we need to create a Composite for the Login application.

  • Select the Designer toolbar button and select GWT > GWT Java UI > Composite from the pull-down menu.

  • Create GWT Composite

  • Enter Login as the name of the Composite and click Finish.

  • New Composite
    Composite created and opened in Source mode.
    Login Composite Source
    Switch to Design mode and Add a  VerticalPanel to the Composite.

  • Click on the VerticalPanel from the Palette and drop it onto the Composite (hover the mouse on the Composite and click the left-mouse button to place the component). You should now see an empty VerticalPanel.

  • Empty Login Composite
    Add a Label widget to the VerticalPanel.

  • On the Palette, scroll down to the Widgets category and click on the Label widget from the Palette and drop it onto the Vertical Panel.

  • Add New Label

  • Replace the default label text to Sign in to your account and press Enter. That sets the text property of the Label widget.

  • Sign in Label
    To easily structure the widgets, add a FlexTable panel.

  • In the Panels section on the Palette, click Flextable and place it into the VerticalPanel.

  • Add the following widgets to the FlexTable and arrange it as follows:

  • Add a Label and change the text property to Username:
  • Add a TextBox next to the Username and change the variable property to textBoxUsername.
  • Add another Label below the Username and change the text property to Password:
  • Add another TextBox next to the Password and change the Variable property to textBoxPassword.
  • Add a CheckBox below the Password and change the text property to Remember me on this computer.
  • Add a Button below the checkbox and set the text property to Sign In.
  • Save your work.
  • You should end up with something like this screen.
    Complete Login Composite

    4. Create and apply CSS styles

    Let's create a CSS style for the Label widgets.

  • Click on the CSS toolbar item to open the CSS Style Editor.

  • Open CSS Editor
    The CSS Style Editor opens.
    CSS Editor

  • Click the Add...button to open the New rule dialog.

  • New CSS Rule

  • Change the name to .gwt-Label-Login and click OK.
  • With the .gwt-Label-Login selected, click the Edit... button.

  • CSS Editor

  • Set any attributes you want and click OK.

  • When you're done, you should have something similar to this:
    CSS Editor

  • Click OK to close the CSS editor.
  • Select each of the Label widgets and set the styleName property to .gwt-Label-Login.

  • Assign styleName
    Following the same procedure, create a style for the checkbox and set the styleName property.
    Open the Login class and this is how it looks like with some css styling. Make sure to Save your work.
    Login with styling

    5. Add Event Handlers

    First, let's convert the text boxes from local to field variables.

  • Still on the Login class, switch to Design mode, select the Username text box and click the Convert local to field button from the properties pane. Do the same with the Password text box.

  • Now, let's add an onClick event for the "Sign In" button.

  • Right-click the Sign In button and select Add event handler > click > onClick.

  • As you can see a ClickHandler has been added and all you have to do is implement the onClick event.

  • Add the following import statement:

  • import com.google.gwt.user.client.Window;

  • then add the following code into the onClick() event:

  • 
    if (textBoxUsername.getText().length() == 0
     || textBoxPassword.getText().length() == 0) {
     Window.alert("Username or password is empty."); 
    }

  • Save your code.

  • 6. Add the Login Composite to the LoginManager module.


  • Open the LoginManager in Design mode and delete the initial Click me! button. You should now see an empty module with the default rootPanel.
  • Add a HorizontalPanel within the rootPanel. Drag the bottom right corner of the HorizontalPanel to make it bigger.
  • Add a VerticalPanel to the HorizontalPanel.
  • Add a Label to the VerticalPanel and set the Label's text property to Welcome to my login page and the styleName property to .gwt-Label-Login.
  • To add the Login composite to the module, select Choose Component from the Palette.

  • Choose Component button

  • In the Open type search dialog, enter Login and select the Login - com.gwt.tutorial.LoginManager.client item and click OK.

  • Choose Component dialog

  • Place the widget in the LoginManager inside the HorizontalPanel as shown.

  • LoginManager with Composite

  • Click Save.

  • 7. Run your Application in Hostedmode.


  • In the Package explorer, right-click the LoginManager and select Run As > GWT Application.

  • Launch Browser

  • Click the Launch Default Browser button.
  • Click the Sign In button. A message dialog should come up.

  • You should now see the LoginManager application similar to the screen below.
    Run application

  • Close the application.

  • 8. Build and Deploy.


  • Select the LoginManager and click click on the Deploy Module button in the main Eclipse toolbar to open the Deployment dialog

  • Deploy Module
    Deployment configuration

  • Specify the server deployment options and click OK.
  • Tuesday, December 18, 2012

    How To Decompress Files From A ZIP File Using JAVA


    How To Decompress Files From A ZIP File Using JAVA


    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.List;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;

    public class UnZip
    {
        List<String> fileList;
        //private static final String INPUT_ZIP_FILE = "C:\\MyFile.zip";
        private static final String INPUT_ZIP_FILE = "D:\\FileExtractTesting\\Demo.zip";
        private static final String OUTPUT_FOLDER = "D:\\FileExtractTesting";

        public static void main( String[] args )
        {
        UnZip unZip = new UnZip();
        unZip.unZipIt(INPUT_ZIP_FILE,OUTPUT_FOLDER);
        }

        /**
         * Unzip it
         * @param zipFile input zip file
         * @param output zip file output folder
         */
        public void unZipIt(String zipFile, String outputFolder){

         byte[] buffer = new byte[1024];

         try{

        //create output directory is not exists
        File folder = new File(OUTPUT_FOLDER);
        if(!folder.exists()){
        folder.mkdir();
        }

        //get the zip file content
        ZipInputStream zis =
        new ZipInputStream(new FileInputStream(zipFile));
        //get the zipped file list entry
        ZipEntry ze = zis.getNextEntry();

        while(ze!=null){

          String fileName = ze.getName();
               File newFile = new File(outputFolder + File.separator + fileName);

               System.out.println("file unzip : "+ newFile.getAbsoluteFile());

                //create all non exists folders
                //else you will hit FileNotFoundException for compressed folder
                new File(newFile.getParent()).mkdirs();

                FileOutputStream fos = new FileOutputStream(newFile);            

                int len;
                while ((len = zis.read(buffer)) > 0) {
            fos.write(buffer, 0, len);
                }

                fos.close();  
                ze = zis.getNextEntry();
        }

            zis.closeEntry();
        zis.close();

        System.out.println("Successfully File Unzip Develop By Sagar");

        }catch(IOException ex){
           ex.printStackTrace();
        }
       }  
    }

    Sunday, December 16, 2012

    Using JQuery and CouchDb to build a simple AJAX web application


    I am Sagar S. Vasule initially wrote this post a couple of months ago, while trying out writing a blog on wordpress. That blog didn't go anywhere, but I thought this tutorial on writing an AJAX web application with JQuery and CouchDb might still be of interest to developers playing with CouchDb. Certainly I couldn't find anything similar at the time
    I assume that you have CouchDb 0.10 and CouchApp 0.5 installed. Later versions may work, but no guarantees.
    First, go to http://127.0.0.1:5984/_utils and create a database called "addressbook". Because we'll be making the functionality to display data before the functionality to create or update it, it's a good idea to use the built-in CouchDb web interface to add a couple of documents. The initial version of our webapp will let us store a mobile number for each person, so add the following 2 documents:
    1. {"type""address""name""Fred""mobile""555-0001"}  
    2. {"type""address""name""Barney""mobile""555-0002"}  
    CouchDb uses design documents to expose the database to the world, but editing design documents directly gets a little painful. Couchapp eases this pain, by breaking design documents out into a set of directories and files on the local filesystem representing shows, views, and so on, which can be pushed to the CouchDb server at will. We need to create a couchapp design document, and also a view to retrieve the phone numbers, which we can do using couchapp at the command-line:
    couchapp generate app addressbook
    couchapp generate view addressbook phonenumbers
    The first line creates a directory called addressbook with a skeleton design document set up, and the second creates a view in the design document.
    We can push this to the server using:
    couchapp push addressbook http://127.0.0.1:5984/addressbook
    If you look at the database using the web interface now, you should see the design document "_design/addressbook" in addition to the documents representing the two phone numbers.
    The view we will need simply gives each name and mobile number, with name as key, so the view is sorted by name. No reduce function is required, so delete addressbook/views/phonenumbers/reduce.js, and put the following in addressbook/views/phonenumbers/map.js
    1. function(doc) {  
    2.   if (doc.type &amp;&amp; doc.type == "address" &amp;&amp; doc.name &amp;&amp; doc.mobile) {  
    3.     emit(doc.name, doc.mobile);  
    4.   }  
    5. }  
    Push the couchapp to the server using
    couchapp push addressbook http://127.0.0.1:5984/addressbook
    and check that you can see the view at http://127.0.0.1:5984/addressbook/_design/addressbook/_view/phonenumbers
    Couchapp has set up an initial index.html for us, which we can edit at addressbook/_attachments/index.html, and view at http://127.0.0.1:5984/addressbook/_design/addressbook/index.html. Make sure that you can view the file ok. You should then alter index.html to contain:

    1. <!DOCTYPE html>  
    2. <html>  
    3.   <head>  
    4.     <title>Simple address book</title>  
    5.     <link rel="stylesheet" href="style/main.css" type="text/css">  
    6. <span style="white-space: pre;"> </span><script src="/_utils/script/json2.js"></script>  
    7. <span style="white-space: pre;"> </span><script src="/_utils/script/jquery.js?1.3.1"></script>  
    8. <span style="white-space: pre;"> </span><script src="/_utils/script/jquery.couch.js?0.9.0"></script>  
    9. <span style="white-space: pre;"> </span><script type="text/javascript">  
    10. <span style="white-space: pre;"> </span></script>  
    11.   </head>  
    12.   <body>  
    13.     <h1>Simple address book</h1>  
    14. <span style="white-space: pre;"> </span><div id="add"><button type="button" id="add">Add</button></div>  
    15.     <div id="addressbook"></div>  
    16.   </body>  
    17. </html>  

    The head contains a title, a link to a stylesheet, imports jQuery and jQuery Couch. These are used by the CouchDb web interface, and included with CouchDb by default. It then has a space for our own javascript to go - more on this later. The body contains an add button within a div, and an empty div called addressbook. The app will display address book entries in the addressbook div.
    We use javascript to access data in the CouchDb, and to process events from the browser, such as buttons and links being clicked. Conceptually, we can think of CouchDb as the Model, the DOM representing the HTML shown to the user as being the view, and our javascript as being the Controller, albeit with relatively little separation in this example.
    Javascript typically uses a continuation-style to process events. For example, we call asynchronous functions, for example to request data from CouchDb, and pass them a function to call when they return, eg to update the view with the data we receive. A simple example:
    1. $.couch.db("addressbook").saveDoc(  
    2.   {type: "address", name: "Wilma", mobile: "555-003"},  
    3.   {success: function() { alert("Saved ok."); }}  
    4. );  
    This example saves a new document to the Couch database, and if successful, pops up an alert.
    Another example is jQuery, which calls functions when links or buttons are clicked. The following example will trigger an alert whenever an "a" element is clicked (ie a hyperlink):
    1. $("a").click(function() { alert("Click"); })  
    jQuery uses selectors to control what elements of an HTML document will trigger functions. In the above example, the selector applied to all "a" elements. We can use "a#blah" to select all "a" elements with an id attribute of "blah", or "a.blah" to select all "a" elements with a class of blah. Selectors form a mini-language and the jQuery documentation gives more details.
    The first javascript we add is called when the base document has finished loading. It retrieves the JSON object of the phonenumbers view from CouchDb. When the JSON object is retrieved a continuation iterates over each row in the view, adding a div for each row containing the name, phonenumber and links to edit and delete it:
    1.   $db = $.couch.db("addressbook");  
    2.   
    3.   function refreshAddressbook() {  
    4.    $("div#addressbook").empty();  
    5.    $db.view("addressbook/phonenumbers", {  
    6.     success: function(data) {  
    7.      for (i in data.rows) {  
    8.       id = data.rows[i].id;  
    9.       name = data.rows[i].key;  
    10.       phonenumber = data.rows[i].value;  
    11.       html = '<div class="address">' +  
    12.        '<span class="name">' + name + '</span> ' +  
    13.        '<span class="phonenumber">' + phonenumber + '</span> ' +  
    14.        '<a href="#" class="edit">edit</a> '+  
    15.        '<a href="#" class="delete">delete</a> '+  
    16.        '</div>';  
    17.       $("div#addressbook").append(html);  
    18.      }  
    19.    }});  
    20.   }  
    21.   
    22.   $(document).ready(function() {   
    23.    refreshAddressbook();  
    24.   });  
    A few things to note:
    • We have created a variable $db to access the CouchDb database. If we change the name of the database, this means we only have to change one place.
    • The function called on success(ful retrieval of data from CouchDb) takes a parameter, data, which is the data returned fromt the view.
    • We call the function from a continuation passed to $(document).ready(). This ensures that we won't request data until the HTML document is fully loaded.
    • The links have an id, which is the id of the document representing the address book entry.
    If we push to the server now, using
    couchapp push addressbook http://127.0.0.1:5984/addressbook
    and refresh in the browser, we should see the page load and then populate with phone numbers from the database. The add button and the edit and delete links will be inactive, but at least the R part of our CRUD app works.
    The next thing to focus on is deleting entries. A nice way for this to work is for the delete link, when clicked, to pop up further links to confirm or cancel deletion. We can use jQuery to insert these links in the div for the address book entry when the delete links are created.
    But this poses a problem - jQuery binds functions to the DOM elements that exist at the time. The links we are proposing adding do not exist when the $(document).ready continuation is called, so we cannot bind functions to them until they are created. Fortunately, there is a trick we can use. Events such as clicks propogate up the DOM tree if they are not processed - so a click will first be processed by the a element, if a handler exists, else it will be processed by the containing div, for example, if a handler exists, all the way up to the document itself. The continuation takes a parameter, which can be used to determine the exact element that was clicked.
    In our example, we can bind a function to the click event of div#addressbook, and then check whether the click came from an edit link, a delete link, or the confirm or delete links we will create. Add the following to the $(document).ready continuation:

    1. $("div#addressbook").click(function(event) {  
    2.   var $tgt = $(event.target);  
    3.   if ($tgt.is('a')) {  
    4.      id = $tgt.attr("id");  
    5.      if ($tgt.hasClass("edit")) {  
    6.       // TODO: implement edit functionality     
    7.      }  
    8.      if ($tgt.hasClass("delete")) {  
    9.       html = '<span class="deleteconfirm">Sure? <a href="#" class="dodelete">Yes</a> <a href="#" class="canceldelete">No</a></span>';  
    10.       $tgt.parent().append(html);  
    11.      }  
    12.      if ($tgt.hasClass("dodelete")) {  
    13.       $db.openDoc(id, { success: function(doc) {  
    14.        $db.removeDoc(doc, { success: function() {  
    15.         $tgt.parents("div.address").remove();       
    16.        }})  
    17.       }});        
    18.      }  
    19.      if ($tgt.hasClass("canceldelete")) {  
    20.       $tgt.parents("span.deleteconfirm").remove();  
    21.      }  
    22.     }  
    23.    });  

    This code runs when any element in the addressbook div is clicked. It gets the clicked element, the id of that target element (which we set above to be the relevant CouchDb document's id), and then runs different code depending on the class of the clicked element. If the link with class "delete" is clicked, we append two new links - "Yes" with class "dodelete", and "No" with class "canceldelete" - within a span with class deleteconfirm. Then, if a link with class "canceldelete" is clicked, we remove the relevent "confirmdelete" span from the DOM to delete the confirm message. On the other hand, if a link with class "dodelete" is clicked, we call $db.openDoc to retrieve the document to delete from CouchDb, and pass it, using a success continuation to $db.removeDoc. We need to retrieve the document prior to deletion in CouchDb, to avoid deleting from an older version than the most current in the database. If this is successful, we remove the parent address div from the DOM, to match the database. Take a deep breath, and read that again.
    If you push this design document to CouchDb, you should be able to delete entries from the address book. However, you will have to use the CouchDb built-in interface to re-add them at this point.
    We adopt a similar approach for editing or creating new entries - clicking the button or link exposes a form to enter new details. CouchDb allows us to save a document with an id to indicate an update, or without an id to indicate that one should be generated, and a new document created. Consequently, we can use the same form for creating and editing if we are careful.

    Add the following function between the refreshAddressbook function and the $(document).ready
    1. function addUpdateForm(target, existingDoc) {  
    2.   html = '<form name="update" id="update" action=""><table>' +  
    3.     '<tr><td>Name</td><td>Number</td></tr>' +  
    4.     '<tr>' +  
    5.       '<td><input type="text" name="name" id="name" value="' +  
    6. <span style="white-space: pre;"> </span>    (existingDoc ? existingDoc.name : "") + '"/></td>' +  
    7.       '<td><input type="text" name="mobile" id="mobile"/ value="' +   
    8. <span style="white-space: pre;"> </span>    (existingDoc ? existingDoc.mobile : "") + '"></td>' +   
    9.       '<td><input type="submit" name="submit" class="update" value="' +   
    10. <span style="white-space: pre;"> </span>    (existingDoc?"Update":"Add") + '"/></td>' +   
    11.       '<td><input type="submit" name="cancel" class="cancel" value="Cancel"/></td>' +   
    12.     '</tr>' +  
    13.   '</table></form>';  
    14.   target.append(html);  
    15.   target.children("form#update").data("existingDoc", existingDoc);  
    16. }  

    Apologies for the inelegant table. I would love to hear a better way for laying out forms. In the meantime, this does the job. And the job is that it appends a form to the target element. If existingDoc is provided, its name and mobile values are used to populate the form, else blanks are used. Further, the existing document is attached to the form, so it can be updated with new values provided by the user to save data later.
    To display the form when an edit link is clicked, add the following in place of the edit TODO above:
    1.      if ($tgt.hasClass("edit")) {  
    2.       $("button#add").show();  
    3.       $("form#update").remove();  
    4.       $db.openDoc(id, { success: function(doc) {  
    5.         addUpdateForm($tgt.parent(), doc);  
    6.       }});        
    7.     }  
     And to display the form when the add button is clicked, add a continuation to the bottom of the $(document).ready continuation:
    1.    $("button#add").click(function(event) {     
    2.     $("form#update").remove();  
    3.     $("button#add").hide();  
    4.     addUpdateForm($("div#add"));  
    5.    });   
    Note that we hide the add button when it is clicked, and show it otherwise. We also remove any existing forms, so only one form shows at any time.
    Finally, we need to process the events when the update(/add) button is hit, or the cancel button. We could adopt the same approach as above, of binding to an element up the hierarchy, but I've chosen to demonstrate a different approach. The .live method can be used to bind to a selector, and to any future elements that selector applies to. That is, as new DOM elements are created, the continuation will apply to them also. Here is an example to bind the click events, of input elements of class "cancel", which hides the form and shows the add button when the cancel button is pressed:
    1.     $("input.cancel").live('click', function(event) {  
    2.     $("button#add").show();  
    3.     $("form#update").remove();  
    4.     return false;  
    5.    });    
     You should add this to the end of the $(document).ready continuation.
    Finally, we need to process the update/add event. The key here is to pick up the existing CouchDb document, if it exists, from the form DOM element we attached it to. This ensures we are updating a CouchDb document with the appropriate id and revision. If there is no existing document, we can populate an empty JSON object, and CouchDb will save it as a new document with a uniquely generated id. Here is the continuation and binding to add to $(document).ready:
    1.    $("input.update").live('click', function(event) {  
    2.     var $tgt = $(event.target);  
    3.     var $form = $tgt.parents("form#update");  
    4.     var $doc = $form.data('existingDoc') || {};  
    5.     $doc.type = "address";  
    6.     $doc.name = $form.find("input#name").val();  
    7.     $doc.mobile = $form.find("input#mobile").val();  
    8.     $db.saveDoc(  
    9.      $doc,  
    10.      {success: function() {  
    11.       $("button#add").show();  
    12.       $("form#update").remove();  
    13.       refreshAddressbook();  
    14.     }});  
    15.     return false;  
    16.    });  
    Note that we remove the form and show the button when the document has been saved.
    Ok, that's it. Push this to CouchDb, and reload the page. You should find that you have a perfectly working, albeit minimal, CRUD webapp.
    There are a few other things that you would want to do in production code, which I have left out here for clarity and brevity. Verification functions should be added to the design document, to avoid badly formed data being passed to CouchDb. Errors should be handled, as well as successes. Also, you might want slightly more from an address book webapp. Nonetheless, I hope this is a useful example of using CouchDb and jQuery to make an AJAX webapp.