L18n Compliance Checked

I am currently working on a large Java desktop application, and now I want to add translations. What bothers me about the l18n system is that it does not provide any compilation checks.

In the java system, you have something like HashMapwhere each localized string has a "key" and the translated string has a "value". It looks something like this (taken from sample tutorials ):

Locale currentLocale;
ResourceBundle messages;

currentLocale = new Locale(language, country);

messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
System.out.println(messages.getString("greetings"));

This works well if you have a simple / small application. But in a large application with thousands of translated strings, it may happen that you have a typo in "Key" and therefore get an empty or incorrect string.

With little luck, the application throws RuntimeExceptionto tell you about this, but even then it is possible that you have not even reached this point, because the wrong “key” is used in a dialog box that may not be displayed under certain circumstances (say, this dialog box with an error).

To prevent this from happening, using a system that offers verification of compliance with the “keys” used will be a better idea. This, for example, is used in Android, where you specify resources in an XML file, which is then indexed and mapped to the class (including the "keys" used). This way you get something like this (from Android docs ):

// Set the text on a TextView object using a resource ID
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);

"", ( "" IDE).

, - , / script, (R.java). Android Eclipse ( IDE ) .

: , Java? , ?

+5
4

. -, , . ..

messages.getString("greetings");

messages.getString(I18.GREETINGS_CODE);

;

public class I18 {

  public static final String GREETINGS_CODE = "greetings";

}

, I18 . - , . , , .

+4

, , .

:

1. , . . . , . , , . Resource Bundles . , , Localizers .
. . , , .
, - . ( , , - L10n). ( ), ResourceBundle.Control. . ( ), .

2. ResourceBundle. - MissingResourceException , , , , , , ( ), - , , (! The.key.does.not.exist!) - Eclipse "Externalize Strings" ". Resource Helper, ResourceBundle, . ( , , , , ResourceBundle.Control). , , , ..
. - . ( , ), , , - . . , , () . , , ( ). , . , , IDE .

3. , Factory ( ), . , Factory . , :

ResourceHelper helper = ResourceFactory(
                          ResourceFactory.Bundles.ERRORS, Locale locale);

4. , . , ( ) , :

:

  • validation.invalid.username.error
  • validation.enter.pass.label
  • validation.dialog.title
  • menu.main.file.open.item
  • login.dialog.ok.button

(label, dialog.title, item, error, message, pattern ..) . . , ( , "", "", "", "" ).

+3

, . , . - , , . . , , , , . ,

+2

, c10n - , ( @eee, !).

The whole idea is to free you from writing keys that are vulnerable to errors and replace them with simple Java interface methods, checked by compilation time, annotated with translation values.

For instance:

public interface Bundle{
  @En("Hello, World!")
  @De("Hallo Welt!")
  String greeting();
}

// ... somewhere in your code
public class MyClass{
  private static final Bundle bundle = C10N.get(Bundle.class);

  public void myMethod(){
    System.out.println(bundle.greeting());
  }
}

You can perform any refactoring on the interface Bundle, rename and move methods, add additional interfaces, extend them, make them up. As long as it compiles with javac, you can be sure that you will see the correct translation.

See the link in more detail .

+1
source

All Articles