Package net.sf.mmm.util.nls.api

Provides the API for the native language support (NLS).

See:
          Description

Interface Summary
NlsArgumentParser The NlsArgumentParser is used to parse an NlsArgument.
NlsFormatter<O> This is the interface for a formatter of an arbitrary object in a localized way.
NlsFormatterManager This is the interface for a manager of NlsFormatters.
NlsFormatterPlugin<O> This interface extends NlsFormatter with the methods required to register this automatically as plugin via injection.
NlsLocalizer This is the interface for a localizer that simplifies the localization of messages via NlsMessages.
NlsMessage This is the interface for an internationalized message.
NlsMessageFactory This is the interface for a factory used to create instances of NlsMessage.
NlsMessageFormatter This is the interface for a formatter of a message-text.
NlsMessageFormatterFactory This is the interface to create an NlsFormatter.
NlsObject This is the interface for an object with native language support.
NlsResourceLocator A NlsResourceLocator is used to find a localized resource.
NlsTemplate This interface represents the template for an internationalized text that can be translated to a given Locale.
NlsTemplateResolver This is the callback interface for translating a text-message to a Locale-specific language.
NlsThrowable This is the interface for exceptions and runtime exceptions with real native language support (NLS).
 

Class Summary
NlsAccess This is an ugly static accessor for the NlsMessageFactory used to create instances of NlsMessage and allowing to exchange the default implementation.
NlsArgument This class represents an argument of an NlsMessage.
 

Exception Summary
AbstractNlsException This is an abstract base implementation of a checked exception with real native language support (NLS).
AbstractNlsRuntimeException This is an abstract base implementation of an unchecked exception with real native language support (NLS).
ComposedException An ComposedException combines a list of exceptions in one single exception.
DuplicateObjectException An DuplicateObjectException is thrown if an object was rejected because it is a duplicate.
IllegalCaseException A IllegalCaseException is thrown if a specific case occurred that should never happen.
NlsClassCastException A NlsClassCastException is analog to an ClassCastException but with native language support.
NlsException This is an abstract base implementation of a checked exception with real native language support (NLS).
NlsIllegalArgumentException A NlsIllegalArgumentException is analog to an IllegalArgumentException but with true native language support.
NlsIllegalStateException A NlsIllegalStateException is analog to an IllegalStateException but with true native language support.
NlsNullPointerException A NlsNullPointerException is analog to an NullPointerException but with native language support.
NlsParseException The NlsParseException is thrown if some data could NOT be parsed because it does NOT match the according format (pattern or grammar).
NlsRuntimeException This the base class for all runtime exceptions of the project.
NlsUnsupportedOperationException An NlsUnsupportedOperationException is thrown if an operation was invoked that is NOT implemented or generally NOT supported.
ObjectNotFoundException An ObjectNotFoundException is thrown if an object was requested but does NOT exist or could NOT be found.
 

Package net.sf.mmm.util.nls.api Description

Provides the API for the native language support (NLS).

NLS API

Applications that should be used by people all over the world need native language support (NLS). The developers task is the internationalization (i18n) where the application has to be written in a way that the code is (mostly) independent from locale-specific informations. This is a challenging task that affects many aspects like GUI-dialogs as well as all text-messages displayed to the end-user. The NLS provided here only addresses the internationalization of text-messages in a way that allows localization (l10n) to the users locale.

The Problem

Java already comes with great i18n support. But IMHO there are some tiny peaces missing to complete the great puzzle of NLS:
There is almost no support if an application needs NLS that is handling multiple users with different locales concurrently (e.g. a web-application).
You will typically store your messages in a
ResourceBundle. Now if you store the technical key of the bundle in a message or exception the receiver needs the proper ResourceBundle to decode it or he ends up with a cryptic message he can NOT understand (e.g. as illustrated by the screenshot).
On the other hand you need to know the locale of the receiver to do the l10n when creating the message or exception with the proper text. This is impossible to solve in may situations or leading to sick design.

The Solution

The solution is quite simple because again Java brings parts of the solution with MessageFormat:
We simply bundle the message in default language together with the separated locale independent arguments in one container object that is called NlsMessage. Here is an example to clarify the idea: The i18n message is "Hi {name}! How are you?" and the language independent argument is the users name e.g. "Lilli". Now if we store these informations together we have all we need. To get the localized message we simply translate the i18n message to the proper language and then fill in the arguments. If we can NOT translate we always have the message in default language which is "Hi Lilli! How are you?".
But how do we translate the i18n message without artificial intelligence? The answer is very easy: We simply use the bundle in default language and do a reverse lookup to get the technical key. Then we can lookup the proper message in the according bundle to translate it to the according locale.
All you have to do is creating a subclass of AbstractResourceBundle that declares public string constants.
 package foo.bar;
 
 public class MyResourceBundle extends AbstractResourceBundle {
   public static final String MSG_SAY_HI = "Hi {name}! How are you?";
   public static final String ERR_LOGIN_IN_USE = "Sorry. The login \"{login}\" is " +
     "already in use. Please choose a different login.";
 }
 
For the automatic reverse-lookup create the file META-INF/net.sf.mmm/nls-bundles with the fully qualified name of your bundle-class (foo.bar.MyResourceBundle) as content. From your code you only need to create the NlsMessage using this constants:

  String userName = "Lilli";
  NlsMessage msg = NlsAccess.getFactory().create(MyResourceBundle.MSG_SAY_HI, "name", userName);

For exceptions there is additional support via NlsException and NlsRuntimeException. Simply derive your declared exceptions from one of these classes:
 public class LoginAlreadyInUseException extends NlsException {
   public LoginAlreadyInUseException(String usedLogin) {
     super(MyResourceBundle.ERR_LOGIN_IN_USE, usedLogin);
   }
 }
 
Now if you throw a LoginAlreadyInUseException, it will behave as a "regular" exception with an English message. Additionally it has methods getLocalizedMessage and printStackTrace that take a Locale and optionally a NlsTemplateResolver as argument. For localization you can create property files with the translations of your NLS-bundle. E.g. foo/bar/MyResourceBundle_de.properties with this content:
 MSG_SAY_HI = Hallo {name}! Wie geht es Dir?
 LOGIN_IN_USE = Es tut uns leid. Das Login "{login}" ist bereits vergeben. Bitte wählen Sie ein anderes Login.
 
In order to support you with creating and maintaining the localized properties, this solution also comes with the ResourceBundleSynchronizer.

Conclusion

As we have seen the NLS provided here makes it very easy for developers to write and maintain internationalized code. While messages are spread throughout the code there are only very view places where these messages are actually displayed to the end-user. At these places you need to figure out the users locale.

The NlsMessage allows to store an internationalized message together with the language independent arguments.

The localization (translation to native language) is easily performed by NlsMessage.getLocalizedMessage(java.util.Locale).

For exceptions there is additional support via NlsThrowable.



Copyright © 2001-2010 mmm-Team. All Rights Reserved.