5 Internationalization
A commonLogger may have a Resource Bundle name associated with it. The
corresponding Resource Bundle can be used to map between raw message strings
and localized message strings.
The Common Logging Framework relies on the underlying logging implementation
to take into account the Resource Bundle by requesting the appropriate
API. When instantiated a commonLogger object can be associated with a ResourceBundle
name by provided in the getLogger method on the LoggerFactory.
The following class named, logi18n, illustrates how the Common
Logging Framework manages i18n.
import com.hp.mw.common.util.logging.CommonLevel;
import com.hp.mw.common.util.logging.commonLogger;
import com.hp.mw.common.util.logging.LoggerFactory;
import com.hp.mw.common.util.logging.LogManager;
import java.util.*;
public class logi18n{
static LoggerFactory
log_fac = LogManager.getLogFactory();
static String
language = System.getProperty("language", "en");
static String
country = System.getProperty("country", "US");
private static
Locale currentLocale = new Locale(language,country); //(1)
private static
ResourceBundle log_mesg =
ResourceBundle.getBundle("logging_msg", currentLocale); // (2)
static commonLogger
mylog = (CommonLogger)log_fac.getLogger(logi18n.class.getName(),
"logging_msg_"+language+"_"+country);
public static void
main(String[] args) {
mylog.log(CommonLevel.FATAL,"FATAL_Message");
mylog.log(CommonLevel.INFO,"INFO_Message");
}
} |
Within the logi18n class, messages defined with specific keys are displayed
according to the language or Locale object specified by the application
(1). As mentioned the US English is chosen by default. To determine the
national text associated with a key (given with the log request), The ResourceBundle
object is then created (3) and associated with the “logging_msg” which
indicates to the ResourceBundle to seek a file beginning with its name
as a prefix, where the rest of the file name is obtained with the Locale
object. For instance, if the language chosen by the application is the
US English, the file name to be considered is “logging_msg_en_US.properties”,
while for the French used in France, the file name to be considered will
be “logging_msg_fr_FR.properties”. Such properties file contains
a national corresponding a key provided in the logging request.
The following files illustrate how national texts are provided for
the English and the French. Additional files appropriate to other languages
can be defined in a similar way.
-
logging_msg_en_US.properties
FATAL_Message = This
is a Fatal message
INFO_Message = This
is an Info message
-
logging_msg_fr_FR.properties
FATAL_Message = Ceci
est un message Fatal
INFO_Message = Ceci
est un message pour information
A log message provided with a string key, used as an entry by the ResourceBundle
object to determine the corresponding text in a properties file, may be
associated with a set of arguments for which their positions have previewed
in the properties files. The following example illustrates how a
set of arguments is associated with a key in the properties
file. Assume that the logging_msg_en_US and logging_msg_fr_FR file
contain respectively the following entry:
English
IDENTIFICATION = The
FirstName is {0} and the LastName is {1}
French
IDENTIFICATION = Le
prenom est {0} et le nom est {1}
The class logi18n may extended with:
public class logi18n{
. . .
public static
void main(String[] args) {
Object[]
myParams = new Object[2];
myParams[0]=
“Foo”;
myParams[1]=
“Bar”;
mylog.info("IDENTIFICATION",myParams);
. . .
}
} |
When the logi18n class is executed the variable replacement, defined
with the key named IDENTIFICATION, are specified with the arguments provided
in myParams.
Missing Resource
If a commonLogger object is used to manage i18n, any string key provided
in a logging request should have an entry in the properties file. If not
the commonLogger object accepts the provided key, but uses this key as
a text to be logger in addition to mention that the associated entry does
not exist in the provided bundle name. The following example is an illustration.
In the class logi18n described above we assume that an additional logging
request is invoked on the commonLogger object but using an entry which
does not exist in the properties files
public class logi18n{
. . .
public
static void main(String[] args) {
mylog.log(CommonLevel.FATAL,"Test_Message");
. . .
}
} |
Assuming that the FATAL log level is enabled, and the language is the
French, the produced log message is.
[19 mars 2002
- 10:51:26][main ][FATAL] - String "FATAL_Message" not found in bundle
"logging_msg_fr_FR".
Note that the message is “String “Test Message” is in English”
Per Class/Per Module Resource Bundle
When requested to log a message, a commonLogger object can determine if
the provided message has to be sent as it to the output or corresponds
to a key associated with a resource bundle (then used to retrieve a national
text). To distinguish these two cases, the commonLogger can determine
if a resource bundle is associated with a log request as follow:
-
Default resource bundle associated with the commonLogger;
There are two ways to associate a default resource bundle with a commonLogger:
-
At the creation via the getLogger method defined by the LoggerFactory,
as follow:
commonLogger getLogger(String
key, String resourceBundleName);
-
Set a resource bundle name with the following method defined by the commonLogger
void setResourceBundleName(String
BaseName);
-
Resource bundle name specified with the log request
A set of methods with a “b” suffix (“b” for bundle) have been defined
on the commonLogger interface to allow the possibility to specify the resource
bundle that should be used by the commonLogger to retrieve the String associated
to a message. These methods are: logb, debugb, infob, warnb, errorb and
fatalb.
If requested with a method defining a resource bundle, a commonLogger
object will seek the specified resource bundle. If found, the message is
sought within the loaded resource bundle, If the specified resource bundle
does not exist the commonLogger checks if a default resource bundle has
been specified to use instead.
A commonLogger object can be used either by one particular class or by
a set of classes, which may belong to a particular set we refer as a module.
A class using a commonLogger object can either define its own resource
bundle – resource bundle per class- or share one with other classes – resource
bundle per module.
To enable a class to specify the resource bundle to use for it’s a
log request, methods allowing to provide the resource bundle name are used.
Get the String without logging
An application can request a commonLogger object to obtain a string associated
with a message defined in a resource bundle. The following methods are
provided for this aim – these methods do not sent the message to the output
with a particular log level.
/** Get an object from
the commonLogger using a string key if a default
* ResourceBundle
is associated with it. */
String
getString(String Key) throws MissingResourceException ;
/** Get an object from
the commonLogger using a key and arguments if a default
* ResourceBundle
is associated with it. */
String
getString(String Key, Object[] arguments) throws
MissingResourceException;
/** Get an object from
the commonLogger using a string key in the ResourceBundle
* specified
with BundleName. */
String
getString(String BundleName, String Key) throws
MissingResourceException ;
/** Get an object from
the commonLogger using a key and arguments in the
* ResourceBundle
specified with BundleName.*/
String
getString(String BundleName, String Key, Object[] arguments)
throws MissingResourceException; |
Resource Bundle List
In addition to the possibility to define a default resource bundle name
at the commonLogger creation via the method getLogger (getLogger(String
key, String resourceBundleName), or setResourceBundle, a list of default
resource bundle names can be associated with a commonLogger. Hence, a string
provided with a logging request will be sought not only in one default
resource bundle but in all resource bundles defined in the list. In order
to define such resource bundle list the following class is provided:
package com.hp.mw.common.util.logging;
public class ListBundleNames
{
/**
Constructs a new instance of ListBundleNames */
public
ListBundleNames()
{.
. . }
/** add a resource bundle name in the list */
public
void add(Object obj)
{
. . . }
/**
remove a resource bundle name from the list */
public
void remove(Object obj)
{
. . . }
/**
Determines if a resource bundle name is in the list */
public
boolean contains(Object obj)
{.
. .}
/**
Get the first resource bundle name from the list */
public
Object getFirst()
{.
. . }
/**
Get the last resource bundle name from the list */
public
Object getLast()
{.
. . }
/**
Get a resource bundle name from the list */
public
Object getElement(int index)
{.
. . }
/**
Determines if the list is empty */
public
boolean isEmpty()
{.
. . }
/**
get the nombre of elements in the list */
public
int size()
{.
. . }
} |
The following scenario illustrates how a resource bundle list can be
associated to a commonLogger at is creation and how an element can be removed
from the list.
import com.hp.mw.common.util.logging.CommonLevel;
import com.hp.mw.common.util.logging.commonLogger;
import com.hp.mw.common.util.logging.LoggerFactory;
import com.hp.mw.common.util.logging.LogManager;
import com.hp.mw.common.util.logging.ListBundleNames;
import java.util.*;
public class BundleList{
static
LoggerFactory log_fac = LogManager.getLogFactory();
static
String language = System.getProperty("language", "en");
static
String country = System.getProperty("country", "US");
private
static Locale currentLocale = new Locale(language,country);
static
ListBundleNames myBundList = new ListBundleNames();
static
commonLogger mylog ;
public
static void main(String[] args) {
myBundList.add("logging_msg_"+language+"_"+country);
myBundList.add("logging_msg_test");
System.out.println("My bund list size is : "+myBundList.size());
mylog = (commonLogger)log_fac.getLogger("BundleList", myBundList);
Object[] myParams = new Object[2];
myParams[0]= “Foo”;
myParams[1]= “Bar”;
mylog.info("IDENTIFICATION",myParams);
mylog.log(CommonLevel.FATAL,"FATAL_Message");
mylog.log(CommonLevel.INFO,"INFO_Message");
myBundList.remove("logging_msg_test");
mylog.log(CommonLevel.FATAL,"msg_test");
myBundList.remove("logging_msg_test");
mylog.log(CommonLevel.FATAL,"msg_test");
// NOT found message is returned for the above request
}
} |
Main
Previous
Next