Sunday, July 29, 2007

Make Your Webapp Speak French

Whenever you create a web application that has global implications, you always need to internationalize it. This means it should be able to interact with the user in their browser or selected language. Our latest requirement for the timecard utility is for usability in both English and French. It demonstrates how to internationalize a JSF application using message bundles.

Message bundles are resources provided through properties files. The java.util.ResourceBundle is a convenient class used to access resources availed to the application. Properties files hold key/value pairs of strings.
Creating internationalization property files is typically a manual process: you identify what text on the UI needs to be in alternative languages, create key/value pairs for them in a properties file, then copy the whole set to other properties files - providing translated text in those files. As you can already tell, to change a single text element, you need to update all other files as well. Also, if you change the key, you need to manually update the classes that use that key directly. NetBeans 6.0 does not provide context-sensitive code completion between properties files and Java classes.

To implement the requirement specified, you create two property files - one for English and the other for French, then populate them accordingly. So, if I put in the english.properties title = Timecard Utility, then I need to also put in the french.properties title = Utilité de Carte de Pointage. The application will only look for the title key in the appropriate properties file and print out its string value. In the JSP, you'd need to call the french properties file with:
<f:loadBundle basename="com.strive.research.intl.french" var="lang"/>
(assuming it is in com/strive/research/intl package).

While this strategy works well, it doesn't update strings generated in the application itself and the propery file to use cannot be set dynamically. The solution is to use your managed bean to set which file the JSP should used. To do this, you create an additional variable in the managed bean that can be set based on the user's selection. When the selection is made, an appropriate locale and properties file are set before the page is redisplayed. To be able to print language-appropriate dates and times, you'd need to take advantage of the java.util.Locale class. The image below shows the result of selecting the French language option.



The big advantage of this implementation is that you don't have to change much code to support additional languages. Also, text changes can be made without having to recompile the application.
JSF also provides a mechanism for automatically applying the correct language based on the browser language. You'd need to set that up in faces-config.xml.

Brandon, let me know if you need the source code for this - pretty minor changes - and I'll send it to you. This application is growing bigger and bigger codebase-wise.

A Break On The Bass

This is an Overwater 6-string bass similar to something I'd like to own someday. Reviews of this bass are favorable, but the $2000 price tag is a bummer for most of us.
With a bass guitar like that, you need a stack that includes a cabinet such as this 1500-watt Epifani UL2-610 (about $1500) and a matching amp head (some 900+ watt box from Carvin or GK). O, and don't forget the cool multi-effects pod (like the Boss GT6B) that comes in handy on solo gigs. With equipment like this, I know I'd crank out bass tunes that'd surprise even myself. You begin looking professional at that level.

I've hang out with some bass players that are fond of bragging about their tools or which lengendary bass player they are trying to emulate, and yet when they set up to play, they stink. There's another breed of bass players that use the lowest end equipment (no bragging rights) and yet produce the sweetest grooves. That's the camp I'd rather be in - purely good skill and style. Granted, any good musician should invest in good equipment, but you don't have to go overboard.

I'm probably the weirdest bass player anyone will ever meet: I don't know how to read music (play by feel and ear), don't know who the great bass players and pioneers are, don't even know what equipment I should have, don't practice for my gigs (you'd think I'd be good at improvising, but nah!), don't maintain my equipment well (I haven't changed strings on one of my bass guitar in over a year), and don't play by the rules much. I have my own sound that sometimes works as bass (because I play it on a bass guitar). I'm a little better than a generic bass player, about average in fact, the experience (of 6 years come September) having helped me add some salt to my playing. I think one of my biggest handicaps is my interest in diverse kinds of music. Granted, I don't like opera or metal/hard rock or certain pointless R&B/Hip-hop/Rap music, but I can handle all kinds of music from all over the world based on thei artistic merit. If it has a beat and bass, I'll probably listen to it. That exposure leaves we wanting to learn everything about those kinds of music - so I end up having no influence or specific style. The question "who are your influences?" is often answered with "Hmmmm ...".

But with 2 records under my belt, a couple of recurring studio gigs, several opportunities to play in worship bands, and a few side projects with local artists and musicians, I suppose I don't stink after all. Though, I know there's much more I can do with this skill. Virtuoso players like Victor Wooten get me on fire - a challenge to improve my game. Though I'll probably never play like him, I can learn a lot from his style and technique. My dream would be to have the ability to take a common song and reinvent it from a bass perspective - give it some fresh air and new taste. There's always a danger of "going flat" once you start playing well and often, where you begin to overuse the technique you have with no new skills. That's the runt I want to get out of ... it's a catalyst for burnout if one is ot careful.

When you are busy as I have been, there's not much time to focus on your talent and improve. So in September, I'm dropping most of my engagements to embark on a learning trail - to explore ways I can be a better musician and bass player, add some professionalism to my game, and develop a character that's more consistent with a serious bass player. I'd like to learn new things and implement many of the suggestions and critique I've received over the last few years. Because music is only a hobby at this time, I'd also like to explore what it'd take to become a professional bass player.

My good friend Dave Taylor (a good drummer) had asked me once: "if you were given $1million to just play music and quit your job, would you take it?" The answer may surprise many, but I said "no". The reason is this: I don't care how much I make as long as the tasks keep me challenged enough that I don't get bored to death. For me to stay "alive", I need constant challenges and things to figure out. I could learn some serious grooves that make me a celebrity, but I'm not satisfied if I can never improve on them. With music, there's nothing "unknown" about music in this age, so creativity rests in composing and arranging with what we have now. My day job is n technology research, and the challenges are endless - which keeps me excited and looking forward to what the day may bring. Besides, I'd be a lazy bum if all I had to do was make music (all bills paid for). I think I'd start making bad music eventually just because I have the expectation to make music. This is a weakness in Hollywood studios: they sign a director and ask him to produce 5 movies a year. The pressure will cause him to produce crappy movies sometimes, just to fulfill his end of the bargain.

In any case, I think it's high time I returned to the basics, took a break, learned a few new things meanwhile. If I've made commitments to you already, I'll still honor them. Just don't be surprised when strange (read experimental) sounds come from me .... Also, I continue to be a backup on occasion. They say you never really abandon your talent, but I'm going to try and chill out the public aspect of it.

Saturday, July 28, 2007

Selection Input for JSF Forms

Supposing the client for the timecard utility sends us two new requirements - that users should have an option of entering time as 24-hour or 12-hour format, and be able to review and modify up to 4 previous weeks in addition to the current week. In HTML, this would mean using radio buttons for the time format and a dropdown list for which week is being viewed/modified.
In JSF, you can use any of <h:selectBooleanCheckBox>, <h:selectManyCheckBox>, <h:selectBooleanListBox>, <h:selectManyMenu>, <h:selectOneListBox>, <h:selectOneMenu>, or <h:selectOneRadioButton>. To implement the requirements specified, we use <h:selectOneRadioButton> for radio buttons and <h:selectOneMenu> for the dropdown list.
Fortunately, JSF has the same mechanism for using these components. You create a class that returns SelectItem[] objects, and use it in both the JSP (to populate the components) and the managed bean. The thing to be careful about is to put components that are supposed to be updated together in their own form elements. Only those elements are updated when a button is clicked.

To start with, we create a new Java class in our project that holds the options. Here's the source code for Options.java. It declares the options we need and appropriate getters/setters. It also has a temporary routine to generate the 5 weeks needed. This method can be extended to read this data from a database.
The managed bean can then add attributes that use the options selected in the form. Here's the sources for Timecard2.java. The JSF configuration file would need to be updated with navigation rules (new faces-config.xml) for the options, and the main display JSP updated to show the appropriate components (here's index.java). After you deploy the application, you should have something that looks like this:

With this new build, a user can choose what format to enter time as, and which week to view by selecting the appropriate. This example demonstrates how easily a JSF application can be extended. It also begins cracking at the power of the JSF framework - there's much much more you can do with this technology.

Using Subversion for NetBeans on Windows XP

Any programmer by now knows the value of having a source versioning and change management facility. A day comes when you mess up existing programs or lose your work, and that's where you can check out the latest working version from a repository somewhere. Beyond that, other benefits of using SCM include source code control and configuration management.
Because of simplicity and cost (free), I decided to use Subversion as the SCM solution. Subversion is designed to replace CVS, which I've had some trouble with. My latest aggravation comes from CVS's popular error message "cvs [server aborted]: Couldn't chdir to working directory : Invalid argument" (2.0.51d). Rather than try to resolve the issue, I decided it was time to find another solution, thus Subversion.

We've come to a point in development where we are making a lot of changes to the timecard utility. In order to preserve all our work, we should start checking it into a repository. This will also allow us to branch the application and merge changes from various contributors.
Here's the process for installing Subversion n Windows XP and to use it in NetBeans 6.0 (M10).
  1. Download Subversion from http://subversion.tigris.org/project_packages.html. Choose the binary executables under the Windows section. I'm using version 1.4.4.
  2. Run the executable and note the install directory (C:\Program Files\Subversion).
  3. Add environment variables: SVN_EDITOR = C:\Windows\notepad.exe (to use Notepad as the log editor), and to PATH += C:\Program Files\Subversion\bin (NetBeans needs this).
  4. Create a database directory that'll hold your versioned projects (J:\Subversion). Use the usual Windows Explorer for this.
  5. I want all my NetBeans projects to be versioned under the NetBeans directory in the SVN database. So we create a repository as such - at command prompt, svnadmin create "J:\Subversion\NetBeans". A directory should appear under your SVN database (#4).
  6. The repository in #5 above has a conf directory. Open the svnserv.conf and uncomment anon-access = read, auth-access = write, and password-db = passwd. Save that file.
  7. Open the passwd file with a text editor and add a user under [users] in the form username = password. Save the file.
  8. Create a windows service for SVN: at the command prompt, run sc create svnserver binPath= "\"C:\Program Files\Subversion\bin\svnserve.exe\" --service --root J:\Subversion --listen-port=6043 --listen-host=localhost" DisplayName= "Subversion Repository" depend= Tcpip. Startup is manual, so visit the Services applet and set how you want it to start, and start it.
In NetBeans, import the project into SVN:
  1. Right-click the project -> Versioning | Import Into SVN Repository ...; repository url = svn://localhost:6043/NetBeans, enter the username and password specified earlier. [Next].
  2. Repository folder defaults to the project folder name. I'd leave it like that. [Finish].
That's all! At the completion of each task, you should check your work in. If multiple developers work on the project, synchronize your local workspace with the latest from SVN.