Tuesday, February 2, 2010

Ten Commandments of Egoless Programming

A friend from work forwarded this information to me, which hed extracted from a TechRepublic article and I thought it was pretty interesting. I'm the Apache Software Foundation Group follows this very much, as it reflects how good their software products are and its free!!!

Here are the 10 Commandments of Egoless Programming, my friend willingly shared.

1. Understand and accept that you will make mistakes.
2. You are not your code.
3. No matter how much "karate" you know, someone else will always know more.
4. Don't rewrite code without consultation.
5. Treat people who know less than you with respect, deference, and patience.
6. The only constant in the world is change.
7. The only true authority stems from knowledge, not from position.
8. Fight for what you believe, but gracefully accept defeat.
9. Don't be "the guy in the room."
10. Critique code instead of people-be kind to the coder, not to the code.

Friday, January 8, 2010

Installing Solaris 10 Software Companion CD from ISO Image

To install the software companion from an iso image on a solaris machine follow this steps:

1. Type the command lofiadm -a /export/temp/software.iso. This command creates a block device from a file which can be mounted. The block device will look something like this /dev/lofi/1.

2. Mount the block device by typing this command mount -F hsfs -o ro /dev/lofi/1 /mnt. We are mounting a file system of type hsfs(High Sierra File System) which is basically a representation of our iso image (compact disc). We can also use the cdfs(Compact Disc File System) if the file is being mounted from a cdrom. The ro option basically means its a read-only.

3. You can install one package at a time, but for the purpose of this demo, I'm gonna install all of the packages. Next step is to create an admin file say on this path /var/tmp/admin. The admin file should be created by root user. It contains the following:

mail=
conflict=nocheck
setuid=nocheck
action=nocheck
partial=nocheck
instance=overwrite
idepend=nocheck
rdepend=nocheck
space=check

Now this will install the packages without having the user interact with the package installation.


4. Change directory to the location of the software companion packages relevant to your architecture. In my case I'll be installing it on a Solaris 10 OS. After changing to that directory it should look something like this /mnt/Solaris_Software_Companion/Solaris_sparc/Packages.

5. As a root, execute this command pkgadd -a /var/tmp/admin -d /mnt/Solaris_Software_Companion/Solaris_sparc/Packages. The -a option overrides the default admin file with the one we just created. 

6. Once it executes, it will display all the available packages to be installed and will asks you to install a package or all of the packages. Choose 'all'. Installation will proceed to run.



Friday, January 1, 2010

Installing CouchDB Version 0.10.1 On Fedora 4

I've heard about the hype on CouchDB from this link NoSQL and the design behind it is pretty interesting. It's a different kind of database that doesn't use schemas at all. Built on Erlang which is a well known language solid enough to handle a grand scale of processes without sacrificing performance. Its data structure is a B-tree and uses MapReduce to traverse it at an incredible speed. CouchDB is document based and provides the option of
working online and offline. With its interesting characteristics, I decided to install it on my Fedora machine.

Here are the dependencies I've installed (assuming everything was a downloaded source):
    1. curl-7.19
    2. SpiderMonkey - js-1.7.0
    3. ICU - icu4c-4_2_1
    4. Erlang OTP - otp_src_R13B03
    5. autoconf-2.13

Somebody had provided a script to properly and easily wire SpiderMonkey with CouchDB as can be seen from http://74.125.47.132/search?q=cache:http://dt.in.th/2008-03-03.spidermonkey-linux.html. This is our script:


#!/bin/bash
if test "$USER" = root; then
    wget http://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz -O- | tar xvz
    cd js/src
    make -f Makefile.ref
    mkdir -p /usr/include/smjs/ -v
    cp *.{h,tbl} /usr/include/smjs/ -v
    cd Linux_All_DBG.OBJ
    cp *.h /usr/include/smjs/ -v
    mkdir -p /usr/local/{bin,lib}/ -v
    cp js /usr/local/bin/ -v
    cp libjs.so /usr/local/lib/ -v
else
    echo "You must be root. Try sudo $0"
fi



To ensure that CouchDB will compile properly, use the options --with-js-lib and --with-js-include when installing it. Type the command couchdb to run it. Then try to run this command curl http://127.0.0.1:5984/. You should see something like this {"couchdb":"Welcome","version":"0.10.1"} as the response. This means that the database was successfully installed.

Futon is a great web interface to the database. Be sure to run all tests from Futon. If the URL used to access Futon is say http://localhost:5984/_utils, there are 3 tests that will fail - oauth, replication and security_validation. This is a known issue for some common network configurations. My setup is basically a Windows XP accessing thru Futton the CouchDB server instance  which is installed on a Fedora machine. Both machines are connected via a router without any DNS configurations. Whatever the network configuration is, this URL will always work and all tests passes - http://127.0.0.1:5984/_utils.

I prefer a different ip address used to access Futon so I went ahead and updated two configuration files which are default.ini and local.ini. The settings from local.ini will override the default.ini. Depending on your installation of CouchDB, these files can be found at /usr/local/etc/couchdb directory. Change the binding address to suit your needs.

Tuesday, December 22, 2009

Checksum App for Windows is a Worm!

Do not download the Checksum App from this site http://corz.org/windows/software/checksum/ . Once downloaded and run, a worm is loaded! Please see the image below. I'm glad I had my Lavasoft Ad-Aware running. Somehow my McAfee didn't detect it.




Saturday, November 14, 2009

Internationalizing Numbers and Dates in Java

Locale
It's easy to be tempted to find a tool that can do a specific job. Consider formatting Dates and Numbers for different countries. If you do find a tool, great, but that's just making your application dependent on another tool and redundant since Java already provides you an API that does the job. There's a ton of language support that Java provides. If Klingon would become a language in the future, I'm sure Java will support it, hopefully here on earth.

A Locale in Java is a representation of the Language and the Country. It's also a class. Their's two properties of it that is a must - language id and country code each of which consists of 2 characters. Say if you have the German language, the locale is "de". If the language is still German but of the country Austria then the locale is "de_at". Locale for United States would be "en_US". There's a lot of websites that explains the different locales in different countries so I'm gonna leave it out.

When instantiating a Locale take its important to note what arguments are being passed to its constructor. I've come across a bug in one of the applications I've worked at where a line of code was passing a language id of this form languageId_countryCode where in fact it should only be languageId. If you need to pass both to the constructor, separate those two values out. See example below.

Locale germanLanguageId = new Locale("de_at"); // wrong assignment of locale value.
Locale germanLanguageId = new Locale("de"); // correcet assignment.

If both the language id and country code is needed then it should look like this.

Locale germanLanguageIdAndCountryCode = new Locale("de", "at");

Localized Or Internationalized Date
This is pretty straight forward. Just use the DateFormat class and pass in the right locale to get the right date display as shown below. When you actually want to get an instance of that class, use the factory method getDateInstance(int style, Locale locale).

Date date = new Date(); // Now the date can be of any type as long as its an object.
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
String internationalizedDateString = dateFormat.format(date);

Now depending on your current Locale, let's say we are using the german language id de, their date would actually be in this format. This is due to the fact that we chose the format type SHORT.

dd.mm.yyyy // so for todays date in german it would be 14.11.2009, thank goodness I decided not to write
                   // this yesterday!

Now for locale en_US it would be 11/14/2009. Of course the code will take care of doing the formatting for whatever locale the application is supporting.

Localized or Internationalized Number
First thing to do is to always define the pattern of the number that we would like to show in different locales. When I say pattern, its how many zeros do we want to show and if we don't want to show anything is the value of the number is equal to zero, etc. The DecimalFormat class has a method applyPattern(String pattern) where we can plugin the pattern we want. We can get an instance of this class by using the factory method of NumberFormat and cast it to DecimalFormat as shown below.

float aNumber = 1,500.98;
DecimalFormat decimalFormat = (DecimalFormat)NumberFormat.getInstance(locale); //factory method
decimalFormat.applyPattern("#,##0.00"); //our cool pattern
String internationalizedAndFormattedNumber = decimalFormat.format(aNumber );

Now the pattern #,##0.00 means that the grouping of the number is in thousand. The hash sign is any digit, where if its zero it won't display that number. The zero in the pattern is a digit, where if its zero, it would display as 0. We are also restricting the number of digits after the decimal to two digits. Say if we have a number 1,450.50 in english locale (en_US), upon formatting this to german (de) it should show up as
1.450,50. The comma becomes as period and the period becomes a comma. Of course, if the number we are trying to format is in millions, then our pattern should look something like this #,###,##0.00.

If the pattern is missing, some numbers get displayed in some other locales and some would display just fine. If our number is 0 to be formatted in german it might appear like this 0.0E3 which just confuses our business people looking at our localized spreadsheet. A pattern must be supplied always to display the right number in the right format. If a number in our localized csv file displays as 12.61 and then opened in excel, that number will be translated into a date equal to December 1967. This is the side effect of not supplying a pattern.

One last tip, if an application is processing data and converting it into CSV for excel viewing, remember to replace all carriage line feeds or new lines embedded in a String value with an empty String (" "). Say we have the String "The value\n is supposed to be\n entered here". This value should be in one row on a cell right? But with the new line character \n excel will actually break those strings into 3 rows. It would be

                Cell A
Row 1     The value
Row 2     is supposed to be
Row 3     entered here

Have fun with I18N !


Thursday, October 15, 2009

Working with Deleting/Updating a Set In Hibernate

If a hibernate mapping object contains contains a Set of objects, it's usually configured with the attribute 'set'. If you want hibernate to take care of updating/deleting those objects in the set from the database table, the set attribute cascade must have the value "all-delete-orphan" and properly handled in the code that tries to update it.

Say our parent object is Car and child objects are of type Part. Our set mapping would be of the form below








In order to make the changes to the set elements which are of Part type, the order of the update statements must be of this sequence.

Car car = manufacturer.getCar();

//we want to reduce the number of parts say from 10 to 8.
//If the two parts have the ids 9 and 10, then let's remove it
Set parts = car.getParts()

//iterate through the set and grab the objects with ids 9 and 10

Part part9 = (Part)iter.next();//assuming this is the 9th object in the set
Part part10 = (Part)iter.next();//assuming this is the 10th object in the set

parts.remove(part9);
parts.remove(part10);

//persist to database to update the records

saveOrUpdate(car); //this will merge the differences. the database record will //now have 8 rows instead of 10 for the parts. Also, you can use the merge(car) //method and it will work the same way.

//if you want to delete all parts since its no longer produced, just do this
parts.clear();
saveOrUpdate(car); //then there will be zero entries for the parts in the database table

//When it comes to adding a new part, just add the new part object and persist.
Part part11 = new Part();
//...fill properties
parts.add(part11);
saveOrUpdate(car);

Wednesday, September 30, 2009

JFreeChart LegendTitle Font Change

I've been trying to search the whole day yesterday on how to change the Font for a chart's legend title. JFreeChart doesn't have any good free reference documentation about this use case but I was finally able to figure it out by playing with LegendTitle's methods. The code below works for changing the Font of the current LegendTitle object.

LegendTitle legendTitle = chart.getLegend();
legendTitle.setItemFont(font);
legendTitle.setNotify(true);

The setNotify() method somehow alerts the different objects dependent on the LegentTitle and update it's state. If that is not called, nothing happens. If that method is set to true that means, the current change on the chart, specifically the LegentTitle, call all dependent objects and notify of this change and properly act on it.