content/fr/developer-guide/utility/Internationalization.html (192 lines of code) (raw):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<title>Internationalization</title>
<meta charset="UTF-8"/>
<link rel="stylesheet" type="text/css" href="../book.css"/>
</head>
<body>
<!--
Content below this point is copied in "/static/book/fr/developer-guide.html" file
by the 'org.apache.sis.internal.book.Assembler' class in 'sis-build-helper' module.
-->
<section>
<header>
<h2 id="Internationalization">Internationalisation</h2>
</header>
<p>
Dans une architecture où un programme exécuté sur un serveur fournit ses données à plusieurs clients,
les conventions locales du serveur ne sont pas nécessairement les mêmes que celles des clients.
Les conventions peuvent différer par la langue, mais aussi par la façon d’écrire les valeurs numériques
(même entre deux pays parlant la même langue) ainsi que par le fuseau horaire.
Pour produire des messages conformes aux conventions du client, <abbr>SIS</abbr> emploie
deux approches qui diffèrent par leur niveau de granularité: au niveau des messages eux-mêmes,
ou au niveau des objets produisant les messages. L’approche utilisée détermine aussi s’il est
possible de partager une même instance d’un objet pour toutes les langues.
</p>
<h3 id="LocalizedString">Chaînes de caractères distinctes pour chaque conventions locales</h3>
<p>
Certaines classes ne sont conçues que pour fonctionner selon une convention locale à la fois.
C’est évidemment le cas des implémentations standards de <code>java.text.Format</code>,
puisqu’elles sont entièrement dédiées au travail d’internationalisation.
Mais c’est aussi le cas de d’autres classes moins évidentes comme
<code>javax.imageio.ImageReader</code> et <code>ImageWriter</code>.
Lorsque une de ces classes est implémentée par <abbr>SIS</abbr>,
nous l’identifions en implémentant l’interface <code>org.apache.sis.util.Localized</code>.
La méthode <code class="SIS">getLocale()</code> de cette interface permet alors de déterminer
selon quelles conventions locales l’instance produira ses messages.
</p>
<p>
Une autre classe qui fournit différentes méthodes pour différentes langues est <code>java.lang.Throwable</code>.
L’<abbr>API</abbr> standard du Java définie deux méthodes pour obtenir un message d’erreur:
<code>getMessage()</code> et <code>getLocalizedMessage()</code>.
Habituellement, ces deux méthodes retournent la même chaîne de caractères.
Toutefois certaines exceptions lancées par Apache <abbr>SIS</abbr> peuvent utiliser différentes langues.
La politique que <abbr>SIS</abbr> tente d’appliquer autant que possible est:
</p>
<ul>
<li><code>getMessage()</code> retourne le message dans la langue par défaut de la <abbr title="Java Virtual Machine">JVM</abbr>.
Dans une architecture client-serveur, c’est souvent la langue du système hébergeant le serveur.
C’est la méthode recommandée pour enregistrer des messages dans le journal des événements,
à l’intention des administrateurs systèmes.</li>
<li><code>getLocalizedMessage()</code> retourne le message dans une langue qui dépend du contexte dans lequel l’exception s’est produite.
C’est souvent la langue qui a été configurée pour une instance particulière de <code>Format</code> ou <code class="SIS">DataStore</code>,
que l’on peut présumer être la langue du client se connectant au serveur.
C’est la méthode recommandée pour afficher un message dans une fenêtre sur le poste de l’utilisateur.</li>
</ul>
<div class="example"><p><b>Exemple:</b>
Si une erreur s’est produite alors qu’un client japonais s’est connecté à un serveur européen,
le message fournit par <code>getLocalizedMessage()</code> pourra être envoyé à l’utilisateur au Japon
alors que le message fournit par <code>getMessage()</code> pourra être enregistré dans le journal des événements du serveur.
Ainsi, l’administrateur système pourra plus facilement analyser l’erreur même s’il ne connaît pas la langue du client.
</p></div>
<p>
La classe utilitaire <code>org.apache.sis.util.Exceptions</code> fournit
des méthodes de commodité pour obtenir des messages selon des conventions locales spécifiées
lorsque cette information est disponible.
</p>
<h3 id="InternationalString">Instance unique pour toutes les conventions locales</h3>
<p>
Les <abbr>API</abbr> définit par <abbr>SIS</abbr> ou hérités de GeoAPI privilégient plutôt l’utilisation du type
<code>InternationalString</code> là où une valeur de type <code>String</code> serait susceptible d’être localisée.
Cette approche permet de différer le processus d’internationalisation au moment d’obtenir
une chaîne de caractères plutôt qu’au moment de construire l’objet qui les contient.
C’est particulièrement utile pour les classes immuables qui serviront à créer des instances uniques
indépendamment des conventions locales.
</p>
<div class="example"><p><b>Exemple:</b>
Il existe dans <abbr>SIS</abbr> une seule instance de type
<code>OperationMethod</code> représentant la projection de Mercator, quelle que soit la langue du client.
Mais sa méthode <code class="GeoAPI">getName()</code> fournit (indirectement)
une instance de <code>InternationalString</code> telle que
<code>toString(Locale.ENGLISH)</code> retourne <cite>Mercator Projection</cite>
alors que <code>toString(Locale.FRENCH)</code> retourne <cite>Projection de Mercator</cite>.
</p></div>
<p>
En définissant des objets spatiaux indépendemment des conventions locales, on réduit les risques de sur-coûts de calculs.
Par exemple il est plus facile de détecter que deux cartes emploient la même projection cartographique si cette dernière
est représentée par la même instance de <code>CoordinateOperation</code>, même si la projection
porte différents noms selon les pays. En outre, certain types de <code>CoordinateOperation</code>
peuvent nécessiter des grilles de transformation de coordonnées, ce qui accroît l’intérêt de partager une instance unique
pour des raisons d’économie de mémoire.
</p>
<h3 id="Locale.ROOT">Convention <code>Locale.ROOT</code></h3>
<p>
Toutes les méthodes <abbr>SIS</abbr> recevant ou retournant une valeur de type <code>Locale</code>
acceptent la valeur <code>Locale.ROOT</code>. Cette valeur est interprétée comme signifiant de ne pas localiser le texte.
La notion de <cite>texte non-localisé</cite> est un peu fausse, puisqu’il faut bien choisir une convention de format.
Mais cette convention, bien que très proche de l’anglais, sera généralement légèrement différente.
Par exemple:
</p>
<ul>
<li>
Les identifiants sont écrits tels qu’ils apparaissent dans les diagrammes <abbr>UML</abbr>,
par exemple <cite>blurredImage</cite> au lieu de <cite>Blurred image</cite>.
</li>
<li>
Les dates sont écrites selon le format <abbr>ISO</abbr> 8601,
qui ne correspond pas aux conventions anglaises.
</li>
<li>
Les nombres sont écrits à l’aide de leurs méthodes <code>toString()</code> plutôt qu’à l’aide d’un <code>java.text.NumberFormat</code>.
Il en résulte des différences dans le nombre de chiffres significatifs, l’utilisation de la notation exponentielle et l’absence de séparateur des milliers.
</li>
</ul>
<h3 id="UnicodePoint">Traitement des caractères</h3>
<p>
Les chaînes de caractères en Java utilisent l’encodage UTF-16. Il existe une correspondance directe
entre les valeurs de type <code>char</code> et la très grande majorité des caractères, ce
qui facilite l’utilisation des chaînes lorsque ces caractères suffisent.
Mais certains caractères Unicode ne sont pas représentables par un seul <code>char</code>.
Ces <i>caractères supplémentaires</i> comprennent certains idéogrammes,
mais aussi des symboles routiers et géographiques dans la plage 1F680 à 1F700.
Le support de ces caractères supplémentaires nécessite des itérations un peu plus complexes
que le cas classique où l’on supposait une correspondance directe.
Ainsi, au lieu de la boucle de gauche ci-dessous, les applications internationales devraient
généralement utiliser la boucle de droite:
</p>
<div class="row-of-boxes">
<div>
<div class="caption">Boucle à éviter</div>
<pre style="margin-top: 6pt"><code>for (int i=0; i<string.length(); i++) {
char c = string.charAt(i);
if (Character.isWhitespace(c)) {
// Un espace blanc a été trouvé.
}
}</code></pre>
</div>
<div>
<div class="caption">Boucle recommandée</div>
<pre style="margin-top: 6pt"><code>for (int i=0; i<string.length();) {
int c = string.codePointAt(i);
if (Character.isWhitespace(c)) {
// Un espace blanc a été trouvé.
}
i += Character.charCount(c);
}</code></pre>
</div>
<div>
<div class="caption">Exemples de caractères supplémentaires</div>
<center>(l’affichage dépend des capacités du navigateur)</center>
<p style="font-size: 40px">🚉 🚥 🚧 🚫
🚯 🚸 🚺 🚹 🛄 🚭</p>
</div>
</div>
<p>
<abbr>SIS</abbr> supporte les caractères supplémentaires en utilisant la boucle de droite lorsque nécessaire.
Mais la boucle de gauche reste occasionnellement utilisée lorsqu’il est connu que les caractères recherchés ne sont
pas des caractères supplémentaires, même si la chaîne dans laquelle on fait la recherche peut en contenir.
</p>
<h4 id="Whitespaces">Interprétation des espaces blancs</h4>
<p>
Le Java standard fournit deux méthodes pour déterminer si un caractères est un espace blanc:
<code>Character.isWhitespace(…)</code> et <code>Character.isSpaceChar(…)</code>.
Ces deux méthodes diffèrent dans leurs interprétations des espaces insécables, des tabulations et des retours à la ligne.
La première méthode est conforme à l’interprétation couramment utilisée dans des langages telles que le Java, C/C++ et <abbr>XML</abbr>,
qui considère les tabulations et retours à la ligne comme des espaces blancs,
alors que les espaces insécables sont interprétés comme des caractères non-blanc.
La seconde méthode — strictement conforme à la définition Unicode — fait l’interprétation inverse.
</p>
<p>
<abbr>SIS</abbr> emploie ces deux méthodes dans des contextes différents.
<code>isWhitespace(…)</code> est utilisée pour <em>séparer</em> les éléments d’une liste (nombres, dates, mots, <i>etc.</i>),
tandis que <code>isSpaceChar(…)</code> est utilisée pour ignorer les espaces blancs <em>à l’intérieur</em> d’un seul élément.
</p>
<div class="example"><p><b>Exemple:</b>
Supposons une liste de nombres représentés selon les conventions françaises.
Chaque nombre peut contenir des <em>espace insécables</em> comme séparateurs des milliers,
tandis que les différents nombres de la liste peuvent être séparés par des espaces ordinaires, des tabulations ou des retours à la ligne.
Pendant l’analyse d’un nombre, on veut considérer les espaces insécables comme faisant partie du nombre,
alors qu’une tabulation ou un retour à la ligne indique très probablement une séparation entre ce nombre et le nombre suivant.
On utilisera donc <code>isSpaceChar(…)</code>.
Inversement, lors de la séparation des nombres de la liste, on veut considérer les tabulations et
les retours à la ligne comme des séparateurs mais pas les espaces insécables.
On utilisera donc <code>isWhitespace(…)</code>.
Le rôle des espaces ordinaires, qui pourraient s’appliquer aux deux cas, doit être décidé en amont.
</p></div>
<p>
Dans la pratique, cette distinction se traduit pas une utilisation de <code>isSpaceChar(…)</code>
dans les implémentations de <code>java.text.Format</code>,
et une utilisation de <code>isWhitespace(…)</code> dans pratiquement tout le reste
de la bibliothèque <abbr>SIS</abbr>.
</p>
</section>
</body>
</html>