Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Best practice for managing internationalised database content in JSF  RSS feed

 
ernest fakudze
Ranch Hand
Posts: 216
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'm experimenting with internationalised databases in JSF and I have two questions.

1) What's the best way of managing internationalised database content in JSF? My approach, being an inexperienced developer, is to have 1 database and then in the database have different tables for all my locales. Also, I have declared my sql commands in different resource bundles such as ("select * from salutations_en" in sql_commands_en.properties) and ("select * from salutations_sz in sql_commands_sz.properties). Then, when the user chooses the locale, the application will load the appropriate bundle and executes sql commands from it. Is this the best way of doing this?

2. I ran into one problem with the solution above: I have a drop down menu (h:selectOneMenu) which lists people's salutations such as Mr, Sir, Madame,Dr. It's attached to a ValueChangeListener of a managed bean and it's selectItems are bound to a method that returns a Map in the bean. The method that returns the map executes an sql command (sql string is got from the bundle via binding) against the database and then populate the drop down
list. My problem is that when I change the loacale the application does not reload the page with the new values. I expect it to execute the command "select * from salutaions_sz" and repopulate the drop down list with the new locale data. Any suggestions as to how to get this to work?

Please note, my locale switching mechanism works as the other items (form labes, text etc) switch when the locale is changed. Any pointers would be
greatly appreciated.

Reagrds,
Ernest
[ February 17, 2006: Message edited by: ernest fakudze ]
 
Peter Goldstein
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest,

Reading your post my first question is why does all of this need to be in the database?

If you're dealing with fixed data - that is, large lists of text items that are translated before application deployment - it would seem more efficient to store the data in the resource bundles themselves. Then you would store the resource bundle keys in the database column, and have the presentation tier do the resource bundle lookup.

So is there a particular reason why have you chosen to store all of these strings in the database?
 
ernest fakudze
Ranch Hand
Posts: 216
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Peter,

Thanks for your reply. I do understand what you are saying. Selecting salutations from a database table was just an example. I would store this data in a HashMap and expose that as a backing bean in a real application.
This is fixed data so it can be stored in a bundle probably as a comma delimeted list.

What I really need to know is how would you handle a sitaution where your application needs to serve news items both in English and for the sake of argument say, in German? Would you keep two separate databases or would you have one database and have one table for English and another for German content. Eventually resource bundles won't cut it so we will need the good old database . Please enlighten me.

Thanks,
Ernest
 
Gerardo Tasistro
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I use treemap with the language as the key. I have a similiar situation with a poll system that has to be multilingual (N amount of languages). There is non-internationalized data like the value of the answers, but the selects and the questions themselves have to change based on the selected language. So for example for the Question caption I have a:

TreeMap questions;
String question;

getQuestions returns a treeMap
getQuestion returns the string for the current selected language. Obviously the getter does a lookup inside the treemap to get that.

The interesting thing about this approach (and I've found it handy). Is the way the setter works



So it is really easy to maintain. The treeMap is populated automatically. And all you have to do is change the current language.

Please beware that cases like this which call for editing of multilingual support and switching of languages require special attention to the JSF phases. Switching language requires some "immediate" and/or "actionListeners" getting used. Otherwise you overwrite one language with the other when you submit the page.

Say for example that you have a selectOneMenu with the available languages. Below that all the content in the current language. If you just submit the language change will be set first and then all the content will just overwrite the new selected language. You must go to the render phase just after changing your language and no other form data must be updated.
 
ernest fakudze
Ranch Hand
Posts: 216
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Gerardo,

I guess it's time I went to read more and more about the JSF Request Processing Life Cycle.
 
Peter Goldstein
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest,

I think you may be underestimating the humble ResourceBundle. When most people think of ResourceBundles they think of the properties files underlying PropertyResourceBundle instances. Things like:

MyResources_en.properties

mother=mother
father=father

MyResources_es.properties

mother=madre
father=padre

But there's a lot more to it than that. In short, ResourceBundles are class instances, so you can write a set of ResourceBundles that are backed by just about anything (including database data). The main questions that arises in these implementations are whether the data in question is dynamic and how often refreshes may be required.

For the case of database backed data, I'd define a set of ResourceBundle classes that delegate to a singleton for each group of ResourceBundles. The singleton is responsible for loading the data from the database and refreshing the data either on request or on a timed schedule.

If the data is static, then it's pretty much trivial and I'd strongly recommend this approach. You don't even have to synchronize access to the cache in the singleton.

If the data is somewhat dynamic, then I'd still recommend that you consider this sort of approach, as it means that you can automatically plug into a pre-built i18n system, rather than creating your own. Especially if the set of keys to be accessed is fixed, even if the backing values aren't.

If you need to change data then you can persist the dynamic data using your favorite persistence mechanism, and then refresh the ResourceBundle singleton. Or, you can refresh the singleton cache directly, in a manner similar to the Gerardo's TreeMap idea.

Feeds and such can be handled with timed refreshes of the bundle values.

In any case, it might be worth thinking about. If it's not your cup of tea, then Gerardo's proposal sounds like it could be very effective.

--Peter
 
ernest fakudze
Ranch Hand
Posts: 216
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Peter,

Thanks for taking your time to explain this to me.

When most people think of ResourceBundles they think of the properties files underlying PropertyResourceBundle instances


That's very true in my case. It seems that I need to read up on ResourceBundles. I only know the basics. What resource do you recommend?. I have never developed Java applications in an enterprise environment. I'm learning JSF because I think it's a real investment for the future. And besides, it's really cool. At work we use ColdFusion and classic ASP.
 
Peter Goldstein
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest,

Happy to help.

For stuff like this I generally recommend going straight to the source. So if you want to know more about ResourceBundles, check out the javadoc on Sun's site - http://java.sun.com/j2se/1.5.0/docs/api/java/util/ResourceBundle.html .

You will see that there are only a couple of abstract methods that you need to implement if you want to extend this class. There are a couple of examples in the Javadoc (although I think they may be missing the getKeys() method).

If you download the source distribution for the Java libraries from Sun, you should be able to see how the ListResourceBundle and PropertyResourceBundle classes are implemented - they're pretty simple.

If you're not familiar with the Singleton pattern I mentioned, I'd recommend that you read the "Gang of Four" authored book, Design Patterns. They're generally good things to know, as a good deal of Java development is an implementation of one or more of these patterns (although overdoing the patterns is often a risk). There are also quite a few pages on the web describing Singleton use in Java apps - a Google search should serve you well here.

Anyway, good luck with your project.

--Peter
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!