Vous avez de grandes ambitions pour le programme Java que vous
développez actuellement : quelques millions de téléchargements
à prévoir dans les prochaines semaines. Tout d'abord
félicitations, mais ne vous réjouissez pas trop vite.
Avez-vous pensé à "l'internationaliser"
? Vous n'envisagez tout de même pas de distribuer un programme
où les messages, les formats numériques, les dates,
sont stockés "en dur" dans le programme ?
L'internationalisation consiste à isoler les parties du programme
dépendantes de la langue. Voici comment résoudre une
partie de ces problèmes à l'aide d'un exemple simple
en Java.
Exploiter les codes ISO
Sur la toile, l'anglais règne en maître, certes. Avouez
cependant que lorsqu'on vous donne le choix de choisir votre langue
dans une application, vous choisissez volontiers la vôtre,
d'autant plus si vous ne maîtrisez pas parfaitement le programme
en question.
Par chance, pays
et langages
sont normalisés par des codes ISO
: International Organization for Standardization.
Java utilise cette standardisation pour l'objet "Locale".
On identifie un tel objet en concaténant l'identifiant d'un
"Resource Bundle" (nous verrons plus tard de quoi
il s'agit) avec "_" suivi de deux caractères ISO
représentant le langage, suivi d'un autre "_"
auquel on ajoute cette fois le code du pays ("country
code").
Par exemple...
MyResourceBundle_fr_FR
... Correspond à la langue française utilisée
en France, alors que, petite nuance :
MyResourceBundle_fr_CA
... Correspond à la même langue mais utilisée
au Canada.
Revenons sur la notion de "Resource Bundle". Ces derniers
contiennent des objets "locaux", dans lesquels on trouve
des "ressources" appropriées à la localisation
de l'utilisateur. En isolant ainsi les données dépendantes
de la localisation, vous permettrez à votre programme d'évoluer
et d'être traduit plus tard pourquoi pas dans d'autres langues,
plus facilement.
Les éléments de notre programme
Afin de mieux comprendre comment s'enchaînent les étapes
de l'internationalisation nous allons tenter d'appliquer ses principes
sur un petit programme. Celui-ci est réellement très
simple, il n'affiche au début que "Bonjour", et
"Au revoir" :
public class HelloBye
{
static public void main(String[] args)
{
System.out.println("Bonjour");
System.out.println("Au
revoir ");
}
}
Copiez ce programme dans un fichier reprenant le nom de la classe
: "HelloBye", compilez-le (javac
HelloBye.java) et exécutez-le (java
HelloBye).
Votre programme destiné à être distribué
si massivement ne s'exprime pour le moment qu'en français
: vous prenez des risques.
Voyons comment le rendre plus modulaire et isoler les parties dépendantes
du langage.
Afin de permettre au plus grand nombre, et pas seulement aux programmeurs,
ce qui est un des points importants, de traduire votre programme,
les informations propres à une localisation sont stockées
dans de simples fichiers textes, manipulables par n'importe quel
éditeur de texte. On les appelle des "Properties
Files". Ils sont constitués d'un label, qui ne doit
pas être modifié quelle que soit la langue, et de la
traduction correspondante à ce label dans une langue donnée.
Par défaut nous souhaitons que notre programme s'exprime
en français, cela donne par exemple :
(Nom du fichier : "MessagesBundle.properties")
Accueil = Bonjour
Depart = Au revoir
Nous voulons également convertir notre programme en anglais
et en allemand, nous créeons un "fichier de propriétés"
par langage, notez la dénomination de ceux qui vont suivre,
elle se base sur les codes ISO des pays et langages :
(MessagesBundle_de_DE.properties)
Accueil = Guten Tag
Depart = Auf Wiedersehen
(MessagesBundle_en_US.properties)
Accueil = Hello
Depart = Bye
Ainsi chaque traducteur peut facilement créer un fichier
destiné à enrichir les capacités linguistiques
de votre langage à condition de respecter les codes ISO.
Notre programme demandera à l'utilisateur de spécifier
sa langue mais si jamais vous souhaitez détecter la configuration
par défaut de son système, il faut écrire :
Locale loc = Locale.getDefault();
Vous pouvez sinon la définir manuellement :
locfr = new Locale("fr","FR");
Par la suite notre programme récupèrera, grâce
aux paramètres entrés par l'utilisateur, les informations
suivantes :
String langue = new String(args[0]);
String pays= new String(args[1]);
currentLocale = new Locale(langue, pays);
Le code de notre programme
Nous n'avons pas encore détaillé tous les mécanismes
utilisés par notre programme en vue de son internationalisation,
mais afin d'obtenir une vue d'ensemble des procédés,
voici tout de même son code source, suivi des commentaires
nécessaires :
(Nom du fichier : "HelloByeInt")
import java.util.*;
public class HelloByeInt
{
static public void main(String[] args)
{
String
langue;
String
pays;
// Si
le nombre de paramètres passés en ligne de commande
est != 2.
if (args.length
!= 2)
{
langue
= new String("fr");
pays
= new String("FR");
}
else
{
langue
= new String(args[0]);
pays
= new String(args[1]);
}
Locale
currentLocale;
ResourceBundle
messages;
currentLocale
= new Locale(langue, pays);
messages
= ResourceBundle.getBundle("MessagesBundle", currentLocale);
System.out.println(messages.getString("Accueil"));
System.out.println(messages.getString("Depart"));
}
}
Grâce à ce listing vous voyez sans doute mieux les
procédés s'enchaîner. Vous pouvez tester ce
programme, compilez-le comme le précédent listing
et testez-le de la sorte :
java HelloByeInt
(vous obtenez par défaut : "Bonjour" / "Au
revoir")
java HelloByeInt de DE
(vous obtenez "Guten Tag" / "Auf Wiedersehen")
et enfin
java HelloByeInt en US
(vous obtenez "Hello" / "Bye")
Il nous restait à voir comment créer les "Resource
Bundle", c'est chose faite avec :
messages = ResourceBundle.getBundle("MessagesBundle",
currentLocale);
Les arguments passés à la méthode "getBundle"
permettent d'identifier quel "Properties files" il faut
utiliser. En effet, notre programme ne fonctionne qu'à la
condition de créer les trois fichiers :
- "MessagesBundle_de_DE.properties" : pour la traduction
allemande
- "MessagesBundle_en_US.properties" : pour la traduction
anglaise
- "MessagesBundle.properties" : pour la traduction française
et celle par défaut.
Par la suite la méthode getString permet de récupérer
les champs précis du "Properties file" qui nous
intéressent.
Voici les sources des fichiers impliqués dans ce tutoriel
:
- HelloByeInt.java
- MessagesBundle.properties
- MessagesBundle_de_DE.properties
- MessagesBundle_en_US.properties
Enfin, d'autres ressources pour aller plus loin : (gestion des
caractères unicode, formatage de date ou de monnaie...)
- Sun
- JGuru
/ IBM
|