Tuesday, December 26, 2006

Disruptive what?

Every other day my dad keeps calling me over the phone and asks me, "The computer is asking this question? what should I do?" kinda stuff. Probably the only reason he has reduced these questions is because he assumes I am too damn busy to keep disturbing me during my work hours or he has learnt the secret of working with computers - "Just click on any damn button" :)

I was thinking why the hell working with a dumb machine got to be so hi-fi for normal people. How many times have you visited a bank in india with the teller telling you (pun intended) that the system has poor software and is not responding when you can point blank see that the System is displaying "Network Error". It scares me sometimes. These people really do not UNDERSTAND what is happening. Because understanding is for the "specialists". Has the washing machine you use ever told you something like "DRYER VALVE UNDER HIGH PRESSURE" or something to that effect? It does scare the hell out of most people I would imagine :)

People talk about distruptive technology all the time. So let me tell all you internet pundits and IT gurus staring over your computer screens this. There aint no use of "distruptive technology" than one which people can actually use it for something! Duh!

Let me state what I actually want to happen:

  • Make the computer a simple thing to work with like the iPod. Stop asking stupid questions and please please stop giving choices nobody needs. Probably you should read this
  • All you virus providers, tool providers, whatever providers, I seriously dont want to read your manuals, know what you do, read your groups, forums, contact you for whatever, all I care about is I am going to switch on my computer, I may be want to click on something to launch something, whatever as long as I can actually do it!
    and then I dont care about Krojans, Common Cold Viruses and Ugly Worms, I dont care about back doors or bams or whatever, I am going to browse and do MY JOB.
Sounds simple is'nt it?
  • I dont care if you will make deals with service providers to install Anti-Virus Softwares and Firewalls in their gateway to prevent all hell from breaking loose.
  • I dont care if you are going to install spam filters at the service provider level.
  • I dont care if you are going to CHARGE ME A WEE BIT MORE AT THE SERVICE PROVIDER LEVEL.
  • I certainly dont care if Google takes you all over and makes a one stop shop.
  • I care about my privacy of course. I dont want other people snopping around and I really dont want to actually hear you say you found a solution. All I care about is doing my job the way I want it done.
Most of you think I have gone insane. Let me tell you something. IT Outsourcing is an old world jargon. Consumer IT Outsourcing is the in thing!

WELCOME TO THE WORLD WHERE COMPUTERS ACTUALLY LET YOU DO YOUR JOB!

Sunday, November 26, 2006

*2.0 is disruptive to the nth power!

We have heard about Enterprise 2.0 and Web 2.0 being really disruptive and the possibilities of them churning out un-thought of possibilities and capabilities very real. Here is an example of "Crowd Sourcing" coming to the forefront after wikipedia. We are Smarter is gathering people to write the first book on business by means of Crowd Sourcing! They have even sorted out the problem of Royalties by allowing the authors to decide on what charity the money should go to! While I was reading about this book, I found it really interesting to note that Microlending websites are already up and running to allow individuals to loan money and the decision on to whom the money should go to will be decided solely by the individual! Now who said Web 2.0, SaaS and Enterprise 2.0 are not for the "real" businesses?

Thursday, November 16, 2006

Cool Mashup

I have come across some wierd as well as some cool websites and mashups across the web. But this one mashup happens to be the coolest and wierdest of them all! I came across this website which is a mashup with Satellite Picture capabilities of Google Maps that gives you the ability to send across messages with individual characters being actually character shaped buildings! I mean every character is a building somewhere in the world. Talk about "Messages from Space" :). Ok let me leave you to check this website out. Click Here to take a look.

Wednesday, November 15, 2006

Six Stages of Debugging

I have come across a lot of developer rants, but I think this one is way up there:) Charlie's humor:

The Six Stages of Debugging 1. That can't happen.
2. That doesn't happen on my machine.
3. That shouldn't happen.
4. Why does that happen?
5. Oh, I see.
6. How did that ever work?

Tuesday, September 26, 2006

Excel and VBA - Locking a Cell

Its been a long time I even saw any code in VB let alone VBA. That was until somebody asked me how they could lock a particular cell in excel based on the list selection in another cell.

That as usual sent me googling and finally I managed to write a script that will do the job for me. For writing the code, I opened the excel sheet and pressed Alt + F11 to open the Macro VBA Editor and selected the worksheet for which I wanted to write the functionality for and then wrote this piece of code on the worksheet change event. I wanted to lock cells C1 to C10 based on the value of cell D1.

Private Sub Worksheet_Change(ByVal Target As Range)
If (Intersect(Target, Range("D1")) Is Nothing) Or _
                    (Target.Cells.Count > 1) Or _
                    Not (Target.Column = 4 And Target.Row = 1) Then Exit Sub
         If Range("D1").Value = "V1" Then
                  ActiveSheet.Unprotect
                  Range("A1:IV65536").Locked = False
                  Range("C1:C10").Locked = True
                  ActiveSheet.Protect
         Else
                  ActiveSheet.Unprotect
                  Range("A1:IV65536").Locked = False
         End If
End Sub

Then my colleague wanted something different. He said, that he wanted the user to be alerted that value cannot be entered into a cell based on the selected value of another cell for which I modified the above code slightly to get this:

Private Sub Worksheet_Change(ByVal Target As Range)
If Not (Target.Column = 6 Or _
           Target.Column = 9 Or _
            Target.Column = 12) Then Exit Sub
    If Not (ActiveSheet.Cells(Target.Row, Target.Column - 1).Value = "C")  _
     And Not (ActiveSheet.Cells(Target.Row, Target.Column).Value = "")       
     Then
             MsgBox ("No value possible here")
             ActiveSheet.Cells(Target.Row, Target.Column).Value = ""
    End If
End Sub

The above code alerts the user if the user tries to enter some value in a cell when it makes no sense to do so because of the selected value of another column.

Tuesday, September 19, 2006

Uninstalling Linux without screwing up Windows

I have a Windows XP, Mandrake Linux dual boot PC. I had installed Linux after windows as normally anybody will do.  I had done this almost 2 years back and unfortunately out of nowhere I had given a 2 GB Partition for the Windows Installation Drive. I know, I know...What on earth was I thinking?

My system started complaining of too less space in the OS directory and applications started behaving abnormally (probably because they expected some space in the temp directory and didnt find much). So I decided to uninstall Linux and resize by Windows Installation Partition. The problem was I didnt have a clue how to?

So I went on a search on how to uninstall Linux without screwing up the windows installation because simply deleteing the partition will screw up my MBR and would leave my hard disk useless.

Finally I did finf a way. I used the Windows Installation CD to boot and went inside the Windows Recovery Console (Press F10 or R). I then used the command fixmbr to overwrite my MBR.

Then I restarted the machine which automatically booted to my XP and then used the Windows Device Manager to delete and format the Linux Partitions.

I then used Partition Magic to resize my OS installed Drive and then restarted my machine to apply changes. It all went like a charm!

Friday, August 25, 2006

Custom Cell Renderers and Custom Cell Editors in Swing - Part III

Now lets take a look at how the CustomJTable code looks like. In order to allow external controllers to specify which column of the JTable will render itself as JRadioButtons, we have a method called setRadioGroup.  We also declare the custom Table Model which hides our internal structure and works the Model magic of Swing by extending AbstractTableModel.

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class CustomJTable extends JTable {

  /**
   * Give support for Grouping Radio Buttons in
   * different rows of a specific column in the table
   <br>
   * Optionally also allow a CellRendererValidator
   * which can choose which rows in the table will
   * have the radio button visible
   
   @param columnIndex -
   *            The column to which the grouping must
   *            be enabled
   
   @param validator -
   *            An optional CellRendererValidator to
   *            choose which columns have visible
   *            radio buttons. By default all column
   *            will show the radiobutton
   
   @see CellRendererValidator
   */
  public void setRadioGroup(int columnIndex,
      CellRendererValidator validator) {
    getColumnModel().getColumn(columnIndex)
        .setCellEditor(
            new RadioColumnCellEditor());
    getColumnModel().getColumn(columnIndex)
        .setCellRenderer(
            new RadioColumnRenderer(
                validator));
  }

  public boolean isCellEditable(int rowIndex,
      int vColIndex) {
    return true;
  }

  public Class getColumnClass(int column) {
    Object value = getValueAt(0, column);
    if (value != null)
      return value.getClass();
    else
      return super.getColumnClass(column);
  }

  /**
   * CellRendererValidator - This is an interface
   * that will be implemented by any class that
   * wishes <br>
   * to specify whether a CellRenderer is valid for a
   * specific column and row. <br>
   * This is pretty useful when specific rows of a
   * column will <i>NOT </i> the renderer set for the
   * entire column
   
   @author rajeshv
   */
  public static interface CellRendererValidator {
    public boolean isValid(JTable table,
        int rowIndex, int colIndex);
  }

  public static class CustomJTableModel extends
      AbstractTableModel {
    private List dataList = null;

    private String[] properties = null;

    public CustomJTableModel(List list) {
      dataList = list;
      LinkedHashMap map =
          (LinkedHashMapdataList.get(0);
      Set keySet = map.keySet();
      properties = new String[keySet.size()];
      int index = 0;
      for (Iterator iter = keySet.iterator(); iter
          .hasNext();) {
        properties[index++=
            (Stringiter.next();
      }
    }

    public int getColumnCount() {
      LinkedHashMap table =
          (LinkedHashMapdataList.get(0);
      return table.size();
    }

    public Object getValueAt(int rowIndex,
        int columnIndex) {
      LinkedHashMap table =
          (LinkedHashMapdataList
              .get(rowIndex);
      return table.get(properties[columnIndex]);
    }

    public int getRowCount() {
      return dataList.size();
    }

    public String getColumnName(int columnIndex) {
      return properties[columnIndex];
    }

    public Class getColumnClass(int columnIndex) {
      return String.class;
    }

    public void setValueAt(Object aValue,
        int rowIndex, int columnIndex) {
      LinkedHashMap table =
          (LinkedHashMapdataList
              .get(rowIndex);
      table.put(properties[columnIndex], aValue);
      fireTableCellUpdated(rowIndex, columnIndex);
    }

    public boolean isCellEditable(int rowIndex,
        int columnIndex) {
      return false;
    }
  }

  public static void main(String[] args) {
    CustomJTable table = new CustomJTable();
    LinkedHashMap firstRow = new LinkedHashMap();
    firstRow.put("column1""test1");
    firstRow.put("column2", Boolean.TRUE);
    LinkedHashMap secondRow = new LinkedHashMap();
    secondRow.put("column1""test1");
    secondRow.put("column2", Boolean.FALSE);
    LinkedHashMap thirdRow = new LinkedHashMap();
    thirdRow.put("column1""test1");
    thirdRow.put("column2""test");

    List dataList = new ArrayList();
    dataList.add(firstRow);
    dataList.add(secondRow);
    dataList.add(thirdRow);
    table
        .setModel(new CustomJTable.CustomJTableModel(
            dataList));
    table
        .setRadioGroup(
            1,
            new CustomJTable.CellRendererValidator(){
              public boolean isValid(
                  JTable table,
                  int rowIndex,
                  int colIndex) {
                if (rowIndex == 2) {
                  return false;
                }
                return true;
            });
    JFrame frame = new JFrame();
    frame
        .setDefaultCloseOperation(
                        
JFrame.EXIT_ON_CLOSE);
    frame.setSize(600600);
    frame.getContentPane().add(table);
    frame.setVisible(true);
  }
}

Thursday, August 24, 2006

Custom Cell Renderers and Custom Cell Editors in Swing - Part II


RadioColumnEditor
:
 The Editor is pretty much standard and the method to note is getTableCellEditorComponent() which contains the core logic.



import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;

import javax.swing.JRadioButton;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;

public class RadioColumnCellEditor implements
    ActionListener, TableCellEditor {
  Color currentColor;

  JRadioButton button;

  boolean state;

  public RadioColumnCellEditor() {
    super();
    button = new JRadioButton();
    button.setOpaque(false);
    button.setBackground(Color.WHITE);
    button.addActionListener(this);
  }

  protected EventListenerList listenerList =
      new EventListenerList();

  protected Object value;

  protected ChangeEvent changeEvent = null;

  protected int clickCountToStart = 1;

  public void setCellEditorValue(Object value) {
    this.value = value;
  }

  /**
   * Add a listener to the list that's notified when
   * the editor starts, stops, or cancels editing.
   */
  public void addCellEditorListener(
      CellEditorListener l) {
    listenerList.add(CellEditorListener.class, l);
  }

  /**
   * Remove a listener from the list that's notified
   */
  public void removeCellEditorListener(
      CellEditorListener l) {
    listenerList.remove(CellEditorListener.class,
        l);
  }

  protected void fireEditingStopped() {
    Object[] listeners =
        listenerList.getListenerList();
    for (int i = listeners.length - 2; i >= 0; i -=
        2) {
      if (listeners[i== CellEditorListener.class) {
        if (changeEvent == null)
          changeEvent =
              new ChangeEvent(this);
        ((CellEditorListenerlisteners[i + 1])
            .editingStopped(changeEvent);
      }
    }
  }

  protected void fireEditingCanceled() {
    Object[] listeners =
        listenerList.getListenerList();
    for (int i = listeners.length - 2; i >= 0; i -=
        2) {
      if (listeners[i== CellEditorListener.class) {
        if (changeEvent == null)
          changeEvent =
              new ChangeEvent(this);
        ((CellEditorListenerlisteners[i + 1])
            .editingCanceled(changeEvent);
      }
    }
  }

  public void actionPerformed(ActionEvent event) {
    fireEditingStopped();
  }

  // Implement the one CellEditor method that
  // AbstractCellEditor doesn't.
  public Object getCellEditorValue() {
    return new Boolean(button.isSelected());
  }

  // Implement the one method defined by
  // TableCellEditor.
  public Component getTableCellEditorComponent(
      JTable table, Object value,
      boolean isSelected, int row, int column) {

    if (!value.getClass().getName().equals(
        Boolean.class.getName())) {
      return null;
    }
    button.setSelected(value != null
        && value.getClass().getName().equals(
            Boolean.class.getName())
        && ((Booleanvalue).booleanValue());
    TableModel model = table.getModel();
    // Make all the radioButtons, except the
    // selected
    // TRUE
    for (int i = 0; i < model.getRowCount(); i++) {
      if (model.getValueAt(i, column!= null
          && model
              .getValueAt(i, column)
              .getClass()
              .getName()
              .equals(
                  Boolean.class
                      .getName())) {
        model.setValueAt(Boolean.FALSE, i,
            column);
      }
    }
    model.setValueAt(Boolean.TRUE, row, column);
    button
        .setHorizontalAlignment(
                              
SwingConstants.CENTER);
    return button;
  }

  public boolean stopCellEditing() {
    fireEditingStopped();
    return true;
  }

  public void cancelCellEditing() {
    fireEditingCanceled();
  }

  public boolean shouldSelectCell(EventObject eo) {
    return true;
  }

  public boolean isCellEditable(EventObject eo) {
    return true;
  }
}

Custom Cell Renderers and Custom Cell Editors in Swing - Part I

JTable provides the ability for individual columns to have different renderers and editors. This is very powerful functionality because you can have a Radio Button in one of the columns or a JButton or JComboBox in some columns.


I went ahead a wrote a small JTable Component that displays a Radio Button in one of its columns. I also customized the component to display the radio button only for specific rows in the column and also added functionality to behave as a radio button group!


The JTable that I wrote has the ability for some external controller to specify
which rows of a particular column must render its value as RadioButtons.
I achieved this by writing an interface with a single method which provided
any renderer with the ability to check if the current row, column can be
rendered by itself.


  /**
   * CellRendererValidator - This is an interface 
   * that will be implemented by any class that 
   wishes <br>to specify whether a CellRenderer 
   * is valid for a specific column and row. <br>
   * This is pretty useful when specific rows of a 
   * column will <i>NOT </i> the renderer set for 
   * the entire column
   
   @author rajeshv
   */
  public static interface CellRendererValidator {
    public boolean isValid(JTable table, 
                          int rowIndex,int colIndex);
  }

I also wrote a TableCellRenderer and TableCellEditor for the RadioButton Column. Here the code for Both.


RadioColumnRenderer:



import java.awt.Color;
import java.awt.Component;

import javax.swing.JRadioButton;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;

public class RadioColumnRenderer extends JRadioButton
    implements TableCellRenderer {
  private CustomJTable.CellRendererValidator 
                                    validator = 
null;

  /**
   
   */
  public RadioColumnRenderer(
      CustomJTable.CellRendererValidator validator) {
    this.validator = validator;
  }

  public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    // this is necessary because we may have 
    // values that are not boolean for
    // som of the columns
    this.setSelected(value != null
        && value.getClass().getName().equals(
            Boolean.class.getName())
        && ((Booleanvalue).booleanValue());

    this.setHorizontalAlignment(
                         
SwingConstants.CENTER);
    this.setOpaque(false);
    this.setBackground(Color.WHITE);
    // request the validator to concur that this 
    // column can be rendered as a JRadioButton
    if (validator != null) {
      if (validator.isValid(table, row, column)) {
        return this;
      }
      return null;
    }
    return this;
  }
}

Wednesday, August 09, 2006

Properties extends from HashTable - Sun's mess up

The basic idea of inheritance in the Object Oriented Paradigm is based on "is-a" kind of relationship. Any violation of this violates OO.

Its very interesting to note that, in Sun's java SDK, we have java.util.Properties extending from java.util.Hashtable. That actually sent me guessing.

If Properties was a class that will handle only string key-value pairs, what was the necessity to extend from Hashtable which supports key - Object pairs? I believe the ugly inheritance-composition confusion had forced one of Sun's engineers to make such a choice.

The store method of Properties tries to cast all values to String :P!

Properties doesnt even stop you from using Hashtables methods of put and get!

Well the actual way to have implemented properties must have been to use a Hashtable inside properties (Composition) and then expose whatever methods that you want to.

I am searching for other examples within the SDK where such a blunder still exists :)

Exception Handling in Java - Inheritance

The other day somebody asked a question about exception handling in java. The question was this:
When we override a method in java which throws an exception, why is that we cannot change the exception that the parent class throws?

Well, I set to find out what are the possible scenarios that can occur when we throw different exceptions when overriding methods.

The first case I encounted was when I had a class BaseClass which had a method called testException() throws IOException. When I override this method from a class InheritedClass with a declaration like testException() throws ArrayIndexOutOfBoundsException, the compiler did not complain. I later realised that AIOOBE is a runtime exception so behavior was right.

The second case was when I declared the overriding method to throw an exception of type which happened to be a subclass of the parent exception class. So if I declare testException() throws FileNotFoundException, with the parent class method throwing IOException the compiler behavior was as I expected. Because the subclass can always be auto casted, it did not complain.

The third case was if we try the opposite of the second case. i.r BaseClass - testException() throws FileNotFoundException and the subclass InheritedClass declares, testException() throws IOException. As expected the compiler immedtiately complained of incompatibility between the declarations from the base class to the inherited class.

The fourth case was if I try and throw a totally unrelated exception in the overriding methods throws clause, like BaseClass testException() throws IOException and InheritedClass declares testException() throws SQLException, the compiler again complained of incompatibility.

Summing up:
Case 1: Overriding method throws runtime exception - Allowed
Case 2:Overriding method throws subclass of the exception type declared by the parent method - Allowed
Case 3: Overriding method throws base class of exception type declared by the parent method - NOT Allowed
Case 4: Overriding method throws totally unrelated compile time exception replacing parent method throws clause - NOT Allowed

Basically I realised that it really did not make sense for an overriding method to throw any other class of exception than what the method in the parent class threw. Java ofcourse allows you the possiblity to add exceptions in overriding methods.

Thursday, August 03, 2006

Accessing MSSQL Server Database Transaction Log via JDBC

Wanting to access the transaction log, I found that dbcc is a god way to do it via the SQL Query Analyzer. However, programatically via jdbc, I was curious whether the same command will work returning a result set. It turned out to be nothing to access the transaction log using dbcc and the MSSQLServer's jdbc driver. I added three jar files in the classpath: msbase.jar, mssqlserver.jar, msutil.jar and started writing the program :

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

public class TestMSQLServer {

  public static void testDBCC() {
    String DRIVER =
        "com.microsoft.jdbc."
            "sqlserver.SQLServerDriver";
    String DBURL =
        "jdbc:microsoft:sqlserver: "
            "//localhost:1433;";

    Connection connection = null;
    Statement stmt = null;
    ResultSet rs = null;
    ResultSetMetaData metadata = null;
    try {
      Class.forName(DRIVER);
      connection =
          DriverManager.getConnection(DBURL,
              "sa""sa");
      stmt = connection.createStatement();
      rs =
          stmt
              .executeQuery("dbcc log (master,2)");
      metadata = rs.getMetaData();
      int noOfColumns =
          metadata.getColumnCount();
      int noOfDashes = 0;
      for (int i = 1; i <= noOfColumns; i++) {
        String columnName =
            metadata.getColumnName(i);
        System.out.print(columnName + "\t");
        noOfDashes +=
            (columnName.length() 4);
      }
      System.out.println();
      for (int i = 0; i < noOfDashes; i++) {
        System.out.print("-");
      }
      System.out.println();
      while (rs.next()) {
        for (int i = 1; i <= noOfColumns; i++) {
          System.out.print(rs
              .getObject(metadata
                  .getColumnName(i))
              "\t");
        }

        System.out.println();

      }
    catch (Exception e) {
      e.printStackTrace();
    finally {
      try {
        if (rs != null) {
          rs.close();
        }
        if (stmt != null) {
          stmt.close();
        }
        if (connection != null) {
          connection.close();
        }
      catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) {
    testDBCC();
  }

}

Tuesday, July 25, 2006

Integrating PHP - Apache in windows

I was trying to intgrate php into apache. My PHP version was PHP 5.1.4 and Apache was Apache 2.0.58 in a Windows XP machine.

I added my php5_apache entry into the httpd.conf of apache
"LoadModule php5_module d:/php/php5apache2.dll"

Then I added
"PHPIniDir d:/php
AddType application/x-httpd-php .php "

In the php.ini file I had uncommented "extension=php_mysql.dll" because I wanted php to use mysql and Apache was simply refusing to load the dll saying "D:\PHP\ext\php_mysql.dll is not found!" So much for legible error messages! Then I was trying to troubleshoot this thingy when I came across this entry which proved to be my savior. I just copied libmysql.dll from d:\php to my system32 folder and Apache stoppped complaining!

But I simple couldnt understand why the dll was not being found!

Friday, July 14, 2006

The edge-seater - > converting a cvsnt project to subversion.

Nows when the nightmare starts I thought when I wanted my CVSNT project to be migrated with all details to Subversion. One thing that was in my favour was there was nothing CVSNT specific that I used and my project was pretty simple project.

First I downloaded cvs2svn and extracted it.
Then I downloaded Python and installed it.
I opened a command prompt to the extracted cvs2svn directory and then typed d:\python2.4\python setup.py install and it started pouring out its usual sysouts like
"install
running install
running build
running build_py
creating build
creating build\lib
....
..
running install_scripts
creating D:\Python24\Scripts
copying build\scripts-2.4\cvs2svn -> D:\Python24\Scripts"

Thats it..Python had created cvs2svn and I crossed my first hurdle.

Then I downloaded UnxUpdates because the sort feature is required by cvs2svn.

I made a copy of the cvs folder I wanted to migrate and then decided its time. I had made the choide to do exactly this! Ok enough of build up ...

I went to the folder where I made the CVS copy opened a command prompt and then typed away.

I first added the sort.exe I downloaded from unx to the path

"set path=%path%;;"

Then...here goes....

"D:\Python24\python D:\Python24\Scripts\cvs2svn --fs-type=fsfs --use-cvs -s d:\svnrepo\<svn_repo_name> <cvs_repo_path>"

The -fs-type is to tell the process to use the fsfs file system insted of the berkley thingy and then --use-cvs is to tell it to use cvs rather that RCS!

I waited with baited breath as the sysouts started to roll...

"----- pass 1 -----
Examining all CVS ',v' files...
....
..
Done
----- pass 2 -----
Checking for blocked exclusions...
Checking for forced tags with commits...
Checking for tag/branch mismatches...
Re-synchronizing CVS revision timestamps...
Done
----- pass 3 -----
Sorting CVS revisions...
Done
----- pass 4 -----
Copying CVS revision data from flat file to database...
Finding last CVS revisions for all symbolic names...
Done
----- pass 5 -----
Mapping CVS revisions to Subversion commits...
Creating Subversion r2 (commit)
Creating Subversion r3 (commit)
Creating Subversion r4 (commit)
....
...
.
----- pass 6 -----
Sorting symbolic name source revisions...
"

Yes, finally the sort is working!!!! If the path was not added, the process breaks exactly here!

"Done
----- pass 7 -----
Determining offsets for all symbolic names...
Done.

Done.

cvs2svn Statistics:
------------------
Total CVS Files: 137
Total CVS Revisions: 383
Total Unique Tags: 1
Total Unique Branches: 2
CVS Repos Size in KB: 124765
Total SVN Commits: 120
First Revision Date: Mon Jun 12 14:58:50 2006
Last Revision Date: Wed Jul 12 17:11:14 2006
------------------
Timings:
------------------
pass 1: 1 second
pass 2: 0 seconds
pass 3: 0 seconds
pass 4: 0 seconds
pass 5: 0 seconds
pass 6: 0 seconds
pass 7: 0 seconds
pass 8: 218 seconds
total: 222 seconds"


Thats it!, I had sucessfully migrated my project.