Java, Resourcebundles, Umlaute, I18N, ASCII, UTF-8, BUILD, Ant Task
Wann und wo Umlaute in Java Programmen, Properties (hierzu zählen
auch Resourcebundles) erlaubt und wann verboten sind scheint oftmals
nicht eindeutig definiert zu sein. Dieser Artikel soll etwas
Licht ins Dunkel bringen und zwei mögliche Wege aufzeigen.
Der Einstieg gestaltet sich sehr einfach: Die einzig zu treffende
Entscheidung ist, ob man selbst Umlaute als gültig oder
ungültig definiert, gibt man Properties/Resourcebundles nach
außen (z.B. als Bestandteil einer jar Datei) haben diese frei von
Sonderzeichen wie Umlauten zu sein.
Man muß also überlegen, ob Umlaute in den Resourcebundles
welche von den Entwickler editiert werden (das sind im Normalfall die
Dateien die im CVS/svn/o.ä. liegen) benutzt werden dürfen
oder nicht.
Dafür spricht die natürlich deutlich bessere Lesbarkeit
gegenüber Texten mit kodierten Unicodewerten, dagegen die
Abhängigkeit zur Umgebung auf welcher die Dateien editiert werden.
Ich empfehle die Sicherheit der Lesbarkeit zu bevorzugen.
Je nach Entscheidung hat dies für für den weiteren Ablauf des
Build-Prozess Konsequenzen:
Zur Umwandlung kann in beiden Fällen auf das Programm
native2ascii, welches in jedem
JDK enthalten ist [http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/native2ascii.html],
zurückgegriffen werden.
Erlaubt man Umlaute nicht, so führt man das Programm einmalig auf
der Kommandozeile aus (Aufruf: native2ascii rscbundle_alt
rscbundle_neu). Nach
dem Löschen des "alten" Resourcebundles wird von nun an nur noch
mit der UTF-8 kodierten, "neuen" Version rscbundle_neu
weitergearbeitet.
Erlaubt man hingegen Umlaute, so müssen diese im Build Prozess
durch das
Build-Tool ersetzt werden:
Für eine einfache Integration des native2ascii Programms in den
Buildprozess steht der
Native2Ascii Ant-Task zur Verfügung [http://ant.apache.org/manual/OptionalTasks/native2ascii.html].
Somit lassen sich sehr einfach gültige Resourcebundle Dateien
erzeugen welche dann vom Build-Prozess in das Paket integriert werden
können, die Original-Resourcebundles dürfen natürlich
hierbei nicht verändert werden. Würde man die Änderungen
auf den Originaldateien vornehmen müsste man diese geänderten
Dateien wieder einchecken. Die Entscheidung "Umlaute in Resourcebundles
sind gültig" sollte dann also auch konsequent verfolgt werden.
Sind im Gegensatz hierzu Umlaute nicht erlaubt, muß dass
Auftreten von ungültigen Zeichen (wie Umlaute) zwingend den
Abbruch des
Build-Prozesses zur Folge haben, da hier
keine Konvertierung zur Umwandlung von ungültigen Zeichen
vorgesehen ist.
Was nun deutlich erkennbar sein sollte ist, dass das Konvertieren bzw.
Prüfen auf
jeden Fall Bestandteil des Buildprozesses ist. Wie aber kann eine
Resourcebundle Datei aus dem Build Prozess
geprüft werden?
Ant bietet eine sehr flexible und simple Schnittstellen API um eigene
Tasks zu erstellen.
Dies hat außerdem den Vorteil, dass man z.B. die aus Ant
bekannten filesets sehr
einfach benutzen kann und sich somit keine Gedanken machen muss, wo und
wie die zu prüfenden Dateien definiert werden müssen.
<taskdef
name="resourceCheck"
classpath="../path/to/org.dyndns.fichtner.ant.AntTasks.jar"
classname="org.dyndns.fichtner.ant.tasks.resource.RscBundleCheck"/>
<resourceCheck>
<fileset dir="${client.base}/resource">
<include name="resourcebundle*.properties"/>
</fileset>
</resourceCheck>
Dieses Beispiel prüft alle
Resourcebundles im Verzeichnis ${client.base}/resource
welche dem Namenspattern resourcebundle*.properties
enstprechen
Der rein für die Prüfung
(wie gesagt existieren Werkzeuge für die Konvertierung) von
Resourcebundles ausgelegte Ant Task überprüft folgende
Eigenschaften:
- Eindeutigkeit von Schlüsseln, d.h. ein Schlüssel darf
in
jedem Resourcebundle nur einmal vorkommen
- Quervergleich innerhalb der Resourcebundles, d.h. jeder Schlüssel muss
in allen
Resourcebundles exisiteren
- Keine ASCII Werte > (int) 127 (bis einschließlich
Zeichen 127 sind ASCII- und Unicodezeichen identisch)
- Prüfung auf durchgängige Verwendung von Platzhaltern
(z.B. mailcount={0} neue Mails
(de), mailcount={1} new mails)
würde zum Fehler führen
- Prüfung von gleichbleibender Groß-/Kleinschreibung
(unterschiedliche Schreibweisen können durchaus korrekt sein, z.B.
Substativ house=Haus (de)
entspricht house=house(en))
Zeilen welche mit '# ' oder ';' beginnen werden ignoriert. Dies kann
über die Eigenschaft commentstartchars
gesteuert werden.
Ein Abschalten der ASCII-Wertigkeitsprüfung ist über den
Schalter checkvalues möglich.
Soll beispielweise die Prüfung des ASCII-Wertebereichs
ausgeschaltet werden und nur Zeilen beginnend mit '#' ignoriert werden,
wäre folgender Aufruf im Ant.Skript nötig:
<resourceCheck
checkvalues="false" commentstartchars="#">[...]
Jede Prüfung kann durch den entsprechenden Schalter ein- oder
ausgeschaltet werden.
Sinnvoll ist oft eine Mischung aus failonerror=true und
failonerror=false (Abbruch des Buildprozesses an- oder ausschalten),
z.B. kann nach erfolgreicher Prüfung auf doppelte keys mit
failonerror=true der Task ein zweites Mal mit failonerror=false
aufgerufen werden um die Groß-/Kleinschreibung Prüfung mit
dementsprechenden Hinweisen auf Standard-Error durchlaufen zu lassen.
Der Ant Task kann unter [http://sourceforge.net/projects/rscbundlecheck/]
heruntergeladen geladen und ohne Einschränkung verwendet werden.
Peter Fichtner fichtner@c2tn.de
Ergänzung 15.09.2006:
Kürzlich habe ich eine Implemetierung zur Prüfung von
Resourcebundle Dateien auf Basis eines JUnit Test gesehen.
Eine derartige Lösung macht alleine aus folgenden zwei
Gründen wenig Sinn:
- JUnit ist das falsche Werkzeug: JUnit exisitert zur Prüfung
von (und zur Überwachung auf gleichbleibendes) Verhalten von Units
(z.B. Klassen oder Methoden) und nicht um Dateien auf deren
Inhalt zu prüfen
- JUnit bietet für diese Aufgabe keinerlei Vorteile
gegenüber einer startbaren Main-Klasse (vgl. hierzu Ant Fileset)
Links
The Task is hosted on sourceforge.net http://sourceforge.net/projects/rscbundlecheck