Package usn.i18n.nobundle

This package implements an alternative to traditional approach to Java software internationalization and allows localized resources be referenced via individual class member names rather than by arbitrary strings.

See: Description

Package usn.i18n.nobundle Description

This package implements an alternative to traditional approach to Java software internationalization and allows localized resources be referenced via individual class member names rather than by arbitrary strings. This allows localized resource references be checked at compile time and also facilitates taking advantage of autocompletion aids provided by IDE's.

Version:
2013-06-17

An application using this package would normally:

  • select one of the two approaches to be used for user locale preferences handling:
    • with user preferences handled and optionally specified by a I18nHandler subclass singleton linked to user preferences in an arbitrary application specific manner, possibly queried with the application or specified as part of persisted user preferences in single-user-per-application-instance cases, etc;
    • with user preferences handled by a I18nHandlerInContext subclass singleton capable of detecting user preferences dynamically from an arbitrary application specific context; such contexts may be constituted, without limitation, by ServletRequest, HttpSession, etc;
    in fact there is no tremendous difference between these two approaches when you start following them... :)
  • subclass either I18nHandler or I18nHandlerInContext, providing an application-specific getUserLocaleTags() method and optionally an application-specific getDefaultLocaleTag() method;
  • declare a necessary set of static I18nItem subclass instances, one for every message that requires being internationalized; feel free to have them all in one place or scatter them across your package tree to your best convenience;
  • use them where necessary via their static member names with .s() method being called.

The following classes are intended for direct use by applications:

  • handlers:
    • I18nHandler – to be subclassed by multi-user applications in cases when no explicit user context is available, but it is possible to retrieve user preferences from the application itself;
    • I18nHandlerInContext – to be subclassed by multi-user applications in cases when some sort of user context is available to retrieve user preferences from, like ServletRequest, HttpSession, etc;
    • I18nHandlerForSingleUser – a ready-to-use handler class suitable for single-user (e.g. desktop) applications in cases when it is possible to retrieve user preferences once on application initialization;
    • I18nHandlerForServletRequest – a ready-to-use handler class suitable for HTTP server applications;
    you need just to instantiate a handler of your choice, and it will establish itself as an application-wide singleton by itself;
  • message collection classes to be used as static storage for multi-locale messages or their formatting patterns; these classes comprise a two-dimensional matrix according to their properties:
    • depending on the approach to user context handling:
      • classes to be used together with I18nHandlerInContext subclasses; they have 'InContext' suffix in their names;
      • classes to be used together with basic I18nHandler subclasses, I18nHandlerSingleUser included; they do not have any context-related suffix in their names;
    • depending on the number of the arguments they take for formatting: '0', '1', '2', '3' or 'Any', the latter being the last resort for large number of arguments, lacking the ability to check argument types at compile time.
  • internationalized (i15d) wrappers for main SLF4J classes for logging: I15dLogger and appropriate factory I15dLoggerFactory.

An example of "hello world" application:

 import usn.i18n.nobundle.I15dLogger;
 import usn.i18n.nobundle.I15dLoggerFactory;
 import usn.i18n.nobundle.I18nHandler;
 import usn.i18n.nobundle.I18nItem0;
 import usn.i18n.nobundle.I18nItemAny;
 
 import static usn.i18n.nobundle.LocalizedMessage.lm;
 
 public class MyApplication
   {
     // only 'I18nItemAny' message items are currently supported for logger
     static I18nItemAny LOG_MSG_HELLO = new I18nItemAny
       (lm ("en", "Hello World!"),
        lm ("fr_CA", "Bonjour Monde!")));
     public static I18nItem0 USER_MESSAGE_1 = new I18nItem0
         (lm ("en", "That's cool!"),
          lm ("fr_CA", "C'est le pied!"));
 
     public static void main (String [] args)
       {
         // the 'i18nHandler' variable itself is not needed,
         // we just need to istantiate some 'I18nHandler' subclass,
         // and we do it here subclassing 'I18nHandler' anonymously
         @SuppressWarnings ("unused")
         I18nHandler i18nHandler = new I18nHandler ()
           {
             @Override
             protected String getDefaultLocaleTag ()
               {
                 return "fr_CA";
               } // getDefaultLocaleTag
             @Override
             protected String [] getUserLocaleTags ()
               {
                 // do something application-specific here...
               } // getUserLocaleTags
           };
 
         I15dLogger logger =
           I15dLoggerFactory.getLogger (MyApplication.class);
 
         // for messages without arguments we can use .toString() implicitly
         // instead of explicit .s()
         logger.info (LOG_MSG_HELLO);
 
         System.out.println (USER_MESSAGE_1.s ());
       } // main
   } // class MyApplication
 
Author:
Sergey Ushakov, s-n-ushakov@yandex.ru