Friday, November 25, 2011

Running PostgreSQL From Command Line

This October I enrolled for the online database course offered by Stanford university. I started out with SQLite as the RDBMS of my choice because it is easy to use, needs no installation and one can use it out of the box. But, in case of SQLite simplicity was the main problem too. So, I downloaded the PostgreSQL for windows. Now, as my workstation is normally overloaded (so I can’t afford background services) and also I just wanted to have a no-install distribution; so I downloaded the Zip Archive.

The first problem I faced was that when I started to run my postgres server then it gave me this long error message:
“Execution of PostgreSQL by a user with administrative permissions is not permitted.The server must be started under an unprivileged user ID to prevent possible system security compromises.  See the documentation for more information on how to properly start the server.”

Forums were of no use and mostly people were suggesting to create a non-admin user and use it. But the problem is I can’t do that as I am working a system which doesn’t allow me to do that. So, I read the documentation and found pg_ctl which is a utility to initialize, start, stop, or control a PostgreSQL server. Here are the steps:
  1. CD C:\pgsql\bin (or where ever your postgres bin folder is)
  2. set PGDATA=c:/temp/test
  3. pg_ctl.exe init
    The files belonging to this database system will be owned by user "ABCDXYZ". This user must also own the server process….
  4. Although after the step# 2 it instructs to start your postgres server as "C:/pgsql/bin\postgres" -D "c:/temp/test"; but it is of no use. Instead do this, pg_ctl.exe start
  5. That it, the server is running and the process is owned by the logged in user.
  6. Now for the admin tool, run the ‘pgAdmin3.exe’ (its inside the C:\pgsql\bin)
  7. Now select ‘Add a connection to server’ toolbar button. This will show an image like this and fill in the values as suggested:

  8. Finally this page will come:

Wednesday, September 14, 2011

ANTLR: Global member function in ‘C’ parser & custom error printing

Technorati Tags: ,,

Writing a Java parser using ANTLR is a breeze. And why not ! It is written in Java, the default IDE which comes with it is in Java and etc. But recently I needed a tool for writing C/C++ parsers. My first choice was to go ahead with YACC or BISON. But management of the generated parser is hard (at least to people who are new to them), so I started with ANTLR.
After few rounds of testing the ANTLR seemed ok to me. But the actual problem came when I have to provide my own custom handler for error processing. After some rounds of googling and diving through the documentation I found the solution.

First create a generic handler: exceptionhandler.h
#pragma once  
#include "R2SParser.h"  
#ifdef __cplusplus
extern "C" {
#endif  
void myDisplayRecognitionError (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames);  
#ifdef __cplusplus
}
#endif  
Its sample implementation: exceptionhandler.cpp (taken from antlr3baserecognizer.c)
#include "exceptionhandler.h"
#include <string>  
 
void myDisplayRecognitionError (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames) 
{
    //====================================  
    pANTLR3_PARSER            parser;
    pANTLR3_TREE_PARSER        tparser;
    pANTLR3_INT_STREAM        is;
    pANTLR3_STRING            ttext;
    pANTLR3_STRING            ftext;
    pANTLR3_EXCEPTION        ex;
    pANTLR3_COMMON_TOKEN    theToken;
    pANTLR3_BASE_TREE        theBaseTree;
    pANTLR3_COMMON_TREE        theCommonTree;  
    // Retrieve some info for easy reading.
    //
    ex        =        recognizer->state->exception;
    ttext   =        NULL;  
    std::string error;  
    // See if there is a 'filename' we can use
    //
    /*if    (ex->streamName == NULL)
    {
        if    (((pANTLR3_COMMON_TOKEN)(ex->token))->type == ANTLR3_TOKEN_EOF)
        {
            ANTLR3_FPRINTF(stderr, "-end of input-(");
        }
        else
        {
            ANTLR3_FPRINTF(stderr, "-unknown source-(");
        }
    }
    else
    {
        ftext = ex->streamName->to8(ex->streamName);
        ANTLR3_FPRINTF(stderr, "%s(", ftext->chars);
    }*/  
    // Next comes the line number
    //  
    ANTLR3_FPRINTF(stderr, "%d) ", recognizer->state->exception->line);
    ANTLR3_FPRINTF(stderr, " : error %d : %s", 
        recognizer->state->exception->type,
        (pANTLR3_UINT8)       (recognizer->state->exception->message));  
    // How we determine the next piece is dependent on which thing raised the
    // error.
    //
    switch    (recognizer->type)
    {
    case    ANTLR3_TYPE_PARSER:  
        // Prepare the knowledge we know we have
        //
        parser        = (pANTLR3_PARSER) (recognizer->super);
        if(parser->super == NULL)
        {
            fprintf(stdout, "I think i can use it");
        }else
        {
            fprintf(stdout, "BAD LUCK");
        }  
        tparser        = NULL;
        is            = parser->tstream->istream;
        theToken    = (pANTLR3_COMMON_TOKEN)(recognizer->state->exception->token);
        ttext        = theToken->toString(theToken);  
        ANTLR3_FPRINTF(stderr, ", at offset %d", recognizer->state->exception->charPositionInLine);
        if  (theToken != NULL)
        {
            if (theToken->type == ANTLR3_TOKEN_EOF)
            {
                ANTLR3_FPRINTF(stderr, ", at <EOF>");
            }
            else
            {
                // Guard against null text in a token
                //
                ANTLR3_FPRINTF(stderr, "\n    near %s\n    ", ttext == NULL ? (pANTLR3_UINT8)"<no text for the token>" : ttext->chars);
            }
        }
        break;  
    case    ANTLR3_TYPE_TREE_PARSER:  
        tparser        = (pANTLR3_TREE_PARSER) (recognizer->super);
        parser        = NULL;
        is            = tparser->ctnstream->tnstream->istream;
        theBaseTree    = (pANTLR3_BASE_TREE)(recognizer->state->exception->token);
        ttext        = theBaseTree->toStringTree(theBaseTree);  
        if  (theBaseTree != NULL)
        {
            theCommonTree    = (pANTLR3_COMMON_TREE)        theBaseTree->super;  
            if    (theCommonTree != NULL)
            {
                theToken    = (pANTLR3_COMMON_TOKEN)    theBaseTree->getToken(theBaseTree);
            }
            ANTLR3_FPRINTF(stderr, ", at offset %d", theBaseTree->getCharPositionInLine(theBaseTree));
            ANTLR3_FPRINTF(stderr, ", near %s", ttext->chars);
        }
        break;  
    default:  
        ANTLR3_FPRINTF(stderr, "Base recognizer function displayRecognitionError called by unknown parser type - provide override for this function\n");
        return;
        break;
    }  
     switch  (ex->type)
    {
    case    ANTLR3_UNWANTED_TOKEN_EXCEPTION:  
        if    (tokenNames == NULL)
        {
            ANTLR3_FPRINTF(stderr, " : Extraneous input...");
        }
        else
        {
            if    (ex->expecting == ANTLR3_TOKEN_EOF)
            {
                ANTLR3_FPRINTF(stderr, " : Extraneous input - expected <EOF>\n");
            }
            else
            {
                ANTLR3_FPRINTF(stderr, " : Extraneous input - expected %s ...\n", tokenNames[ex->expecting]);
            }
        }
        break;  
    case    ANTLR3_MISSING_TOKEN_EXCEPTION:  
        if    (tokenNames == NULL)
        {
            ANTLR3_FPRINTF(stderr, " : Missing token (%d)...\n", ex->expecting);
        }
        else
        {
            if    (ex->expecting == ANTLR3_TOKEN_EOF)
            {
                ANTLR3_FPRINTF(stderr, " : Missing <EOF>\n");
            }
            else
            {
                ANTLR3_FPRINTF(stderr, " : Missing %s \n", tokenNames[ex->expecting]);
            }
        }
        break;  
    case    ANTLR3_RECOGNITION_EXCEPTION:  
        ANTLR3_FPRINTF(stderr, " : syntax error...\n");    
        break;  
    case    ANTLR3_MISMATCHED_TOKEN_EXCEPTION:  
        if    (tokenNames == NULL)
        {
            ANTLR3_FPRINTF(stderr, " : syntax error...\n");
        }
        else
        {
            if    (ex->expecting == ANTLR3_TOKEN_EOF)
            {
                ANTLR3_FPRINTF(stderr, " : expected <EOF>\n");
            }
            else
            {
                ANTLR3_FPRINTF(stderr, " : expected %s ...\n", tokenNames[ex->expecting]);
            }
        }
        break;  
    case    ANTLR3_NO_VIABLE_ALT_EXCEPTION:  
        ANTLR3_FPRINTF(stderr, " : cannot match to any predicted input...\n");  
        break;  
    case    ANTLR3_MISMATCHED_SET_EXCEPTION:  
        {
            ANTLR3_UINT32      count;
            ANTLR3_UINT32      bit;
            ANTLR3_UINT32      size;
            ANTLR3_UINT32      numbits;
            pANTLR3_BITSET      errBits;  
            ANTLR3_FPRINTF(stderr, " : unexpected input...\n  expected one of : ");  
            count   = 0;
            errBits = antlr3BitsetLoad        (ex->expectingSet);
            numbits = errBits->numBits        (errBits);
            size    = errBits->size            (errBits);  
            if  (size > 0)
            {
                for    (bit = 1; bit < numbits && count < 8 && count < size; bit++)
                {
                    // TODO: This doesn;t look right - should be asking if the bit is set!!
                    //
                    if  (tokenNames[bit])
                    {
                        ANTLR3_FPRINTF(stderr, "%s%s", count > 0 ? ", " : "", tokenNames[bit]); 
                        count++;
                    }
                }
                ANTLR3_FPRINTF(stderr, "\n");
            }
            else
            {
                ANTLR3_FPRINTF(stderr, "Actually dude, we didn't seem to be expecting anything here, or at least\n");
                ANTLR3_FPRINTF(stderr, "I could not work out what I was expecting, like so many of us these days!\n");
            }
        }
        break;  
    case    ANTLR3_EARLY_EXIT_EXCEPTION:  
        ANTLR3_FPRINTF(stderr, " : missing elements...\n");
        break;  
    default:  
        ANTLR3_FPRINTF(stderr, " : syntax not recognized...\n");
        break;
    }  
    //====================================
}  
Then create a place holder for error message (this is a trimmed down version): errorstruct.h
#pragma once  
#ifndef __ERRORSTRUCT__
#define __ERRORSTRUCT__  
struct errormessage_struct
{
    char* message;
};  
typedef struct errormessage_struct ErrorMessage;
typedef ErrorMessage* pErrorMessage;  
#endif  
Now at this point your ANTLR grammar should have this:
@parser::header {
   #include "errorstruct.h"
   #include "exceptionhandler.h" 
   #define ERRORMESSAGE CTX->errorMessage  
}  
@parser::context
{
    ErrorMessage errorMessage;
}  
@parser::apifuncs {
    RECOGNIZER->displayRecognitionError = myDisplayRecognitionError;
    ERRORMESSAGE.message = NULL;
}
And that’s it. Now you can access your error message any where like this parser->errorMessage.message. Similarly, you can add some member function to the structure (in the above example it is errormessage_struct) and then can use it anywhere.
One point worth noting is that with the above approach you get the free threading, which is built into the code generation and the runtime. Here you get one errorMessage per thread.

References:
  1. http://www.antlr.org/pipermail/antlr-interest/2009-May/034567.html
  2. http://groups.google.com/group/il-antlr-interest/browse_thread/thread/80ec25032e9af7a8?pli=1

Wednesday, April 20, 2011

Testing SWT application with SWTBot

SWTBot is open-source Java based UI/functional testing tool for testing SWT and Eclipse based applications.

SWTBot provides APIs that are simple to read and write. The APIs also hide the complexities involved with SWT and Eclipse. This makes it suitable for UI/functional testing by everyone, not just developers. SWTBot also provides its own set of assertions that are useful for SWT. You can also use your own assertion framework with SWTBot.

There are many articles present for SWTBot for Eclipse Plug-in and RCP applications. Refer the following links for more details:
As the title suggest, the intention of this article to demonstrate the testing of a stand-alone SWT UI. There was a question asked  on the Stackoverflow with the same problem. You can checkout my answer there also. For completeness purpose I am posting it here too.

Well it is very much possible to test simple SWT application with SWTBot. Follow the step as mentioned below.
  1. Download SWTBot for SWT Testing
  2. Put it in the <eclipsehome>/dropins folder (although not required for non-plug-in projects)
  3. Restart your eclipse (not required if you adding the SWTBot jars in a simple Java project)
Now at this point you are ready to play with SWTBot.

For the demo purpose I have written a small Login dialog for you and it will look like this:


>>Code
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SampleSWTUI 
{
   public Shell showGUI(final Display display)
   {
       Shell shell = new Shell(display);
       shell.setLayout(new GridLayout(3,true));
       shell.setText("Sample SWT UI");

       new Label(shell, SWT.NONE).setText("User Name: ");
       final Text nameText = new Text(shell, SWT.BORDER);
       nameText.setText ("");
       GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
       data.horizontalSpan = 2;
       nameText.setLayoutData(data);

       new Label(shell, SWT.NONE).setText("Password: ");
       final Text passwordText = new Text(shell, SWT.BORDER|SWT.PASSWORD);
       passwordText.setText ("");
       data = new GridData(SWT.FILL, SWT.FILL, true, false);
       data.horizontalSpan = 2;
       passwordText.setLayoutData(data);

       Button loginButton = new Button (shell, SWT.PUSH);
       loginButton.setText ("Login");
       data = new GridData(SWT.FILL, SWT.FILL, true, false);
       data.horizontalSpan = 3;
       loginButton.setLayoutData(data);
       loginButton.addSelectionListener(new SelectionAdapter(){
           public void widgetSelected(SelectionEvent e) {
                String user = nameText.getText();
                String password = passwordText.getText();

                System.out.println("\n\n\n");
                if(user.equals("Favonius") && password.equals("abcd123")){
                    System.out.println("Success !!!");
                }else {
                    System.err.println("What the .. !! Anyway it is just a demo !!");
                }                   
           }
       });

       shell.pack();
       shell.open();
       return shell;
   }

   public static void main(String [] args) 
   {
       Display display = new Display();
       Shell shell = new SampleSWTUI().showGUI(display);
       while (!shell.isDisposed()) {
           if (!display.readAndDispatch()) display.sleep();
       }

       display.dispose();
   }
}
Now create a JUnit test case (google for it if you are new to it) . Also add all the jar files present in SWTBot (the one you have downloaded) in your classpath.

Now first create a display (because application needs one). Also get the handle of container in which your widgets/controls are present. In my case it is the Shell. Although the below code is self descriptive, still, I will suggest you to refer its Javadoc.

>>SWTBot Code
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
import org.junit.Test;

import junit.framework.Assert;

public class SWTBotDemo 
{
    @Test
    public void test() 
    {
        SWTBotPreferences.PLAYBACK_DELAY = 100; // slow down tests...Otherwise we won't see anything
  
        Display display = new Display();
        Shell shell = new SampleSWTUI().showGUI(display);
        SWTBot bot = new SWTBot(shell);
  
        SWTBotButton loginButton = bot.button("Login");
        SWTBotText userText = bot.textWithLabel("User Name: ");
        SWTBotText passwordText = bot.textWithLabel("Password: ");
  
        userText.setFocus();
        userText.setText("Superman");
  
        Assert.assertEquals(userText.getText(),"Superman");
  
        passwordText.setFocus();
        passwordText.setText("test123");
  
        Assert.assertEquals(passwordText.getText(),"test123");
  
        loginButton.setFocus();
        loginButton.click(); 
  
  
        userText.setFocus();
        userText.setText("Favonius");
  
        Assert.assertEquals(userText.getText(), "Favonius");
  
        passwordText.setFocus();
        passwordText.setText("abcd123");
  
        Assert.assertEquals(passwordText.getText(), "abcd123");
  
        loginButton.setFocus();
        loginButton.click();
        
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }

        display.dispose();
    }
}
Now all the SWTBot methods and variables are well defined in the source and the source is bundled within the SWTBot jars. So you can always go ahead and hack its source code.

>>Further Reading
  1. SWTBot FAQ

Monday, April 18, 2011

Detecting change in SWT Table's scrollbar visibility

Recently on stackoverflow there was a question asked related to this. The requirement was simple ‘resize all the columns as soon as scrollbar appears or disappears’. Now, if you look deep into the SWT table API then you will notice that there is no direct solution for this because:
  1. There is no way to get the scrollbar handle
  2. Scrollbar does not support any event related to visibility
One can solve this problem by implementing a simple hack. I am using the concept presented in this SWT snippet compute the visible rows in a table. Along with that I am also using SWT Paint Event.

The basic concept is as follows:
  1. Calculate the number of visible rows (items).
  2. Compare it with total number of rows (items).
  3. Do all this in some event which occurs with the addition of rows (items). I have chosen the SWT Paint Event
>> Code
import org.eclipse.swt.*;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class TableScrollVisibilityTest 
{
    private static int count;

    public static void main(String [] args) 
    {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setBounds(10,10,300,300);
        shell.setLayout(new GridLayout(2,true));

        final Table table = new Table(shell, SWT.NONE);
        GridData data = new GridData(GridData.FILL_BOTH);
        data.horizontalSpan = 2;
        table.setLayoutData(data);

        count = 0;

        final Button addItem = new Button (shell, SWT.PUSH);
        addItem.setText ("Add Row");
        data = new GridData(SWT.FILL, SWT.FILL, true, false);
        data.horizontalSpan = 2;
        addItem.setLayoutData(data);

        final Text text = new Text(shell, SWT.BORDER);
        text.setText ("Vertical Scroll Visible - ");
        data = new GridData(SWT.FILL, SWT.FILL, true, false);
        data.horizontalSpan = 2;
        text.setLayoutData(data);


        addItem.addListener (SWT.Selection, new Listener () 
        {
            public void handleEvent (Event e) 
            {
                new TableItem(table, SWT.NONE).setText("item " + count);
                count++;
            }
        });


        table.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                Rectangle rect = table.getClientArea ();
                int itemHeight = table.getItemHeight ();
                int headerHeight = table.getHeaderHeight ();
                int visibleCount = (rect.height - headerHeight + itemHeight - 1) / itemHeight;
                text.setText ("Vertical Scroll Visible - [" + (table.getItemCount()>= visibleCount)+"]");

                      // YOUR CODE HERE
            }
        });


        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }

        display.dispose();
    }

}

>> Output
For itemcount < numberofvisible rows


For itemcount >= numberofvisible rows


Note - If you are going to use the paint event then try keep the calculations minimum as it is called frequently.

Saturday, April 16, 2011

SWT Browser and Javascript

Sometime we feel the need of modifying SWT browser content dynamically. Using getText and modifying it is not the advisable way of changing HTML content. I will suggest you to use execute() method of org.eclipse.swt.browser.Browser. It allows you to fire javascripts on the DOM object of the page.

>> Example
Here in this code I am allowing the page to fully load and then looking for all the links item and then creating a red border around them.

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

public class BrowserTest 
{
 private static Browser browser;

 public static void main(String [] args) 
 {
  Display display = new Display();
  final Shell shell = new Shell(display);
  GridLayout gridLayout = new GridLayout();
  gridLayout.numColumns = 3;
  shell.setLayout(gridLayout);

  createBrowser(shell);

  browser.addProgressListener(new ProgressListener() 
  {
   public void changed(ProgressEvent event) {
   }
   public void completed(ProgressEvent event) {
    changeSomething();
   }
  });

  shell.open();
  browser.setUrl("http://google.com");

  while (!shell.isDisposed()) {
   if (!display.readAndDispatch())
    display.sleep();
  }
  display.dispose();
 }

 protected static void changeSomething() 
 {
  String s = "var allLinks = document.getElementsByTagName('a'); " +
    "for (var i=0, il=allLinks.length; i<il; i++) { " +
     "elm = allLinks[i]; elm.style.border = 'thin solid red';" +
    "}";

  System.out.println(browser.execute(s));
 }

 private static void createBrowser(Shell shell) 
 {
  ToolBar toolbar = new ToolBar(shell, SWT.NONE);
  ToolItem itemGo = new ToolItem(toolbar, SWT.PUSH);
  itemGo.setText("Go");

  GridData data = new GridData();
  data.horizontalSpan = 3;
  toolbar.setLayoutData(data);

  Label labelAddress = new Label(shell, SWT.NONE);
  labelAddress.setText("Address");

  final Text location = new Text(shell, SWT.BORDER);
  data = new GridData();
  data.horizontalAlignment = GridData.FILL;
  data.horizontalSpan = 2;
  data.grabExcessHorizontalSpace = true;
  location.setLayoutData(data);

  try {
   browser = new Browser(shell, SWT.NONE);
  } catch (SWTError e) {
   System.out.println("Could not instantiate Browser: " + e.getMessage());
   //display.dispose();
   return;
  }
  data = new GridData(SWT.FILL, SWT.FILL, true, true);
  data.horizontalSpan = 3;
  browser.setLayoutData(data);

  /* event handling */
  Listener listener = new Listener() 
  {
   public void handleEvent(Event event) 
   {
    ToolItem item = (ToolItem)event.widget;
    String string = item.getText();
    if (string.equals("Go")) browser.setUrl(location.getText());
   }
  };

  browser.addLocationListener(new LocationListener() {
   public void changed(LocationEvent event) {
    if (event.top) location.setText(event.location);
   }
   public void changing(LocationEvent event) {
   }
  });


  itemGo.addListener(SWT.Selection, listener);
  location.addListener(SWT.DefaultSelection, new Listener() {
   public void handleEvent(Event e) {
    browser.setUrl(location.getText());
   }
  });  
 }
}
>>Output


>> Further Reading
  1. Eclipse Article
  2. SWT Snippets