Friday, December 31, 2004

Displaying Dates in American Format

Displaying a date field as a text field in a Web application:

Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("mm/dd/yyyy");
sdf.format(now);

Displays the date as : 12/31/2004

Tuesday, December 28, 2004

Calculating Yesterday's Date

private Date yesterday() {
long calcTime = System.currentTimeMillis() - 86400000L;
Date yesterday = new Date(calcTime);
return yesterday;
}

Tuesday, December 21, 2004

Time for PC Upgrade 2

Just received the 512MB memory card from memory4all.com. Installed it on my m/c which already has 1GB or RAM. This website was nice in that it ran a diagnostic on my machine and recommended a compatible memory card for my PC. After installation my PC is now on Steroids.

Also I got the M$ fingerprint reader for easy login to the PC and websites. The new Bose PC speakers kicks a**. Cool thing about this is that it can be plugged into the Bose Walkman using the adapter shipped along with the package. It was free with the purchase of the Bose Noise Cancellation headphones. This makes it a compact and portable DJ system. The only question is : What is the biggest room that it can perform really well?

Surviving Abrupt Shutdown

Nice article for doing tasks before the program exits. Surviving Abrupt Shutdown

Now I have the following lines of code in the constructor :

shutdownHook = new ShutdownHook();
Runtime.getRuntime().addShutdownHook(shutdownHook);

and the new ShutdownHook class takes a snapshot of the Prevayler system.

/*
* Created on Dec 22, 2004
* @author Bala Paranj
*/
package com.zepho.mailer;

import com.zepho.persistence.UserDAO;

public class ShutdownHook extends Thread {
public void run() {
System.out.println("Taking Prevayler system snapshot before shut down...");
UserDAO userDAO = new UserDAO();
userDAO.backup();// TODO: backup must be taken only once every 24 hours.
}
}

Thus avoiding the reading of commands from multiple files during system startup. This speeds up the system startup.

No more Jar file woes

Good programmers know what to write and what to re-use. When it comes to packaging your application into one jar file for delivery to the customer "Fat Jar Eclipse Plug-In" can help. It is based on One-Jar developed by Dr. P. Simon Tuffs. You can read his article here.

Common usages of the jar tool

Function
Command

Creating a JAR file from individual files
jar cf jar-file input-file...

Creating a JAR file from a directory
jar cf jar-file dir-name

Creating an uncompressed JAR file
jar cf0 jar-file dir-name

Updating a JAR file
jar uf jar-file input-file...

Viewing the contents of a JAR file
jar tf jar-file

Extracting the contents of a JAR file
jar xf jar-file

Extracting specific files from a JAR file
jar xf jar-file archived-file...

Running an application packaged as an executable JAR file
java -jar app.jar

Reference : Explore the power of the JAR file format

Friday, December 17, 2004

Prevayler 2-minute Tutorial

Concise
tutorial on Prevayler.

Here is some sample code based on that tutorial:

/*
* Created on Dec 16, 2004
* @author BXParanj
*/
package registration;

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

import persistence.UserDAO;

public class RegistrationParser {
private String userName;
private String password;

public RegistrationParser(String fileName) {
String index = findIndex();
System.out.println("Index found : " + index);
try
{
// load the driver into memory
Class.forName("org.relique.jdbc.csv.CsvDriver");
// create a connection. The first command line parameter is assumed to
// be the directory in which the .csv files are held
Connection conn = DriverManager.getConnection("jdbc:relique:csv:" + fileName );
// create a Statement object to execute the query with
Statement stmt = conn.createStatement();
// Select the EBK_USERNAME and EBK_PASSWORD columns from lead.csv file
String sqlQuery = "SELECT EBK_USERNAME, EBK_PASSWORD FROM lead WHERE EBK_USERNAME =" + index ;
ResultSet results = stmt.executeQuery(sqlQuery);

while (results.next())
{
userName = results.getString("EBK_USERNAME");
password = results.getString("EBK_PASSWORD");
System.out.println("EBK_USERNAME= " + userName + " EBK_PASSWORD= " + password);
}
// clean up
results.close();
stmt.close();
conn.close();
}
catch(Exception e)
{
System.out.println("Oops-> " + e);
}
}

public static void main(String[] args) {

RegistrationParser rp = new RegistrationParser(args[0]);
System.out.println("Username - " + rp.getUserName() + " Password - " + rp.getPassword());
}

private String findIndex() {
UserDAO userDAO = new UserDAO();
userDAO.list();
String index = userDAO.getNext();
userDAO.delete(index);
System.out.println("AFTER UPDATE - HERE IS THE LIST : ");
userDAO.list();

return index;
}

public String getPassword() {
return password;
}

public String getUserName() {
return userName;
}
}

/*
* Created on Dec 17, 2004
*/
package persistence;

import java.io.Serializable;

import org.apache.commons.collections.MapIterator;
import org.apache.commons.collections.map.ListOrderedMap;

/**
* @author BXParanj
*/
public class UserList implements Serializable {
private ListOrderedMap users = new ListOrderedMap();

public void save(ListOrderedMap users) {
this.users = users;
}

public void remove(String userName) {
users.remove(userName);
}


public void print() {
MapIterator it = users.mapIterator();

while (it.hasNext()) {
Object key = it.next();
Object value = it.getValue();
System.out.println("KEY " + key + " VALUE : " + value);//it.setValue("newValue");
}
// System.out.println("Checking indexing at 99: " + users.get(99));
}

public ListOrderedMap getUsers() {
return users;
}
}

/*
* Created on Dec 17, 2004
*/
package persistence;

import java.util.Date;

import org.apache.commons.collections.map.ListOrderedMap;
import org.prevayler.TransactionWithQuery;

/**
* @author BXParanj
*/

public class SaveUserTransaction implements TransactionWithQuery {

private final ListOrderedMap users ;

public SaveUserTransaction(ListOrderedMap users) {
this.users = users;
}

public Object executeAndQuery(Object prevalentSystem, Date executionTime) throws Exception {

UserList system = (UserList) prevalentSystem;
system.save(users);

return users;
}
}

package persistence;

import java.io.IOException;

import org.apache.commons.collections.map.ListOrderedMap;
import org.prevayler.Prevayler;
import org.prevayler.PrevaylerFactory;

/**
* @author BXParanj
* Created on Dec 17, 2004
*/
public class UserDAO {
private Prevayler prevayler;

public UserDAO() {
// Create a new prevayler. /userlist-base is the tx-journal directory.
try {
prevayler = PrevaylerFactory.createPrevayler(new UserList(), "/userlist-base");
UserList list = (UserList) prevayler.prevalentSystem();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

public void save(ListOrderedMap users ) {
try {
prevayler.execute(new SaveUserTransaction(users));
} catch (Exception e) {
e.printStackTrace();
}
}

public void delete(String userName) {
try {
prevayler.execute(new DeleteUserTransaction(userName));
} catch (Exception e) {
e.printStackTrace();
}
}

public void list() {
UserList list = (UserList) prevayler.prevalentSystem();
list.print();
System.out.println("Listing generated through DAO");
}

public String getNext() {
UserList list = (UserList) prevayler.prevalentSystem();
ListOrderedMap listOrderedMap = list.getUsers();
if(!listOrderedMap.isEmpty())
return (String)listOrderedMap.get(0);

return null;
}

public ListOrderedMap retrieve() {
UserList list = (UserList) prevayler.prevalentSystem();
return list.getUsers();
}
}

package persistence;

import java.util.Date;

import org.prevayler.TransactionWithQuery;

public class ListUserTransaction implements TransactionWithQuery {

public ListUserTransaction() {
}

public Object executeAndQuery(Object prevalentSystem, Date executionTime) throws Exception {

UserList system = (UserList) prevalentSystem;
system.print();

return system;
}
}

/*
* Created on Dec 17, 2004
*/
package persistence;

import java.util.Date;

import org.prevayler.Transaction;

/**
* @author BXParanj
*/

public class DeleteUserTransaction implements Transaction {

private final String userName ;

public DeleteUserTransaction(String userName) {
this.userName = userName;
}

public void executeOn(Object prevalentSystem, Date executionTime) {
UserList system = (UserList) prevalentSystem;
system.remove(userName);
}
}

/*
* Created on Dec 16, 2004
* @author BXParanj
*/
package registration;

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

import org.apache.commons.collections.map.ListOrderedMap;

import persistence.UserDAO;

public class IndexUsers {

public IndexUsers() {
}

public void run(String fileName) {
try
{
// load the driver into memory
Class.forName("org.relique.jdbc.csv.CsvDriver");
// create a connection. The first command line parameter is assumed to
// be the directory in which the .csv files are held
Connection conn = DriverManager.getConnection("jdbc:relique:csv:" + fileName );
// create a Statement object to execute the query with
Statement stmt = conn.createStatement();
// Select the EBK_USERNAME columns from lead.csv file
String sqlQuery = "SELECT EBK_USERNAME FROM lead " ;
ResultSet results = stmt.executeQuery(sqlQuery);

save(results);
// clean up
results.close();
stmt.close();
conn.close();
}
catch(Exception e)
{
System.out.println("Oops-> " + e);
}
}

private void save(ResultSet results) throws Exception {
String userName;
ListOrderedMap userList = new ListOrderedMap();

while (results.next())
{
userName = results.getString("EBK_USERNAME"); System.out.println("EBK_USERNAME= " + userName );
userList.put(userName, "Y");
}
UserDAO userDAO = new UserDAO();
userDAO.save(userList);
}

public static void main(String[] args) {
IndexUsers indexUsers = new IndexUsers();
indexUsers.run(args[0]);
}
}

Tools used :
Jakarta Commons Collections 3.1
Prevayler 2.02.005
and of course cvsjdbc.

Nice thing about this is that I am using DAO to hide the persistence mechanism. I have not complicated the code by making it too generic to accommodate new persistence mechanism.

I have used the Commons Collections API so that I can retain the ordering of the list. I initially tried to use the Properties file instead of Prevayler, problem is that Properties file does not maintain the order.

Thursday, December 16, 2004

Parsing CSV files in 5 minutes or less!

CsvJdbc - a JDBC driver for CSV files Rocks!

I was looking for an utility which can read and parse the CSV files. The open source utility CsvJdbc was perfect for my requirements. It parses the given CSV file with no problem. Just include the csvjdbc.jar in the classpath and start using the API. The command line argument is C:\\test (Java requires the escape character \ for the \, which is the separator). The filename is anything.csv and is stored in the directory specified above. Version is Version 0.10.
The documentation says :
The driver also now supports scrollable result sets.
This following example code shows how these are used.
...

Connection conn = Drivermanager.getConnection("jdbc:relique:csv:" + args[0],props)

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 0);

ResultSet results = stmt.executeQuery("SELECT ID,NAME FROM sample");

resulst.next();
...
results.first();
...
results.previous();
...
results.relative(2);
...
results.absolute(2);
...
But it looks like it is not implemented yet. I got : Oops-> java.lang.UnsupportedOperationException: ResultSet.relative() unsupported error message.

Here is the modified example program that I am using for my purposes:

/*
* Created on Dec 16, 2004
* @author BXParanj
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class RegistrationParser {
private String userName;
private String password;

public RegistrationParser(String fileName) {

}

public static void main(String[] args) {

String index = "fcgp001";
try
{
// load the driver into memory
Class.forName("org.relique.jdbc.csv.CsvDriver");

// create a connection. The first command line parameter is assumed to
// be the directory in which the .csv files are held
Connection conn = DriverManager.getConnection("jdbc:relique:csv:" + args[0] );

// create a Statement object to execute the query with
Statement stmt = conn.createStatement();

// Select the EBK_USERNAME and EBK_PASSWORD columns from lead.csv file

String sqlQuery = "SELECT EBK_USERNAME, EBK_PASSWORD FROM lead WHERE EBK_USERNAME =" + index ;
ResultSet results = stmt.executeQuery(sqlQuery);

// dump out the results
while (results.next())
{
System.out.println("EBK_USERNAME= " + results.getString("EBK_USERNAME") + " EBK_PASSWORD= " + results.getString("EBK_PASSWORD"));
}

// clean up
results.close();
stmt.close();
conn.close();
}
catch(Exception e)
{
System.out.println("Oops-> " + e);
}
}
}

Time for PC upgrade

After almost 4 years I upgraded my home PC from Windows 2000 to XP.
Installing SMTP server messed up the Internet connection on my old OS. I
also flashed the BIOS from 2.9 version to 3.6 to support hard drives > 32G.
This allowed me to install a new hard drive with 160GB capacity. It is a
Western Digital with 7200rpm and 8.9ms seek time. This is faster than
Seagate and Maxtor. For some reason during the upgrade Western Digital
restricted the hard drive capacity to 137GB (XP cannot access beyond 137?).
I should have partitioned the drive to utilize its full capacity. Still
waiting for the 512MB RAM, so that I can increase the memory from 1GB to
1.5GB. Installed a Adaptec 2 fire-port 3 USB 2.0 port card. This made
accessing my external Western Digital hard drive as fast as internal hard
drive. This drive is basically for backup/restore purpose (capacity >
100GB).

Apache JAMES server problem

There is an error in the JAMES server documentation, the
JAVA_HOME=C:\jdk_xyz\ (bin should not be included). When you telnet into the
JAMES server use the syntax : telnet localhost 4555. Note : mail.jar
(JavaMail) and activation.jar (JAF) must be in the build path. I used
Eclipse to run the examples from the tutorials on JAMES server I found at
IBM website. Pretty cool.

Can Prevayler really work ?

Here is a very interesting blog about object persistence:
Prevayler