Seiten

Donnerstag, 20. Juni 2013

CDI Commons – i18n

Immer wieder müssen Anwendungen mit i18n angereichert werden.
Der Std.Weg sieht vor, dass man mit Properties-Dateien die unterschiedlichen Sprachen unterstützt. Nicht nur Sprachen, auch verschiedene Mandanten können so getrennt werden.
Der von Oracle vorgeschlagene Weg sieht dabei wie folgt aus. (Internationalization)

Locale currentLocale; //… wo auch immer das herkommen mag..
ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
System.out.println(messages.getString("greetings"));

Für jedes Locale muss eine Ressourcendatei vorhanden sein.
 
Hier nun der Ansatz per CDI. (Quelltext wie immer unter : Git-Repo )
Im Blog CDI Commons – Param per Annotation habe ich gezeigt wie man 
Parameter per Annotationen übergeben kann. Das reicht natürlich nicht, wenn man z.B. das Datum
unterschiedlich formatieren möchte in Abhängigkeit von Locale und Mandant.
Schön wäre eine Annotation die den RessourcenKey enthält, der dann zur Laufzeit aufgelöst wird.
image
 
Als zusätzliche Anforderung soll das Locale und dabei  verschiedene Level berücksichtigt werden.
Exemplarisch habe ich das hier mit den Leveln
  • Company – firmenweite Vorgaben
  • Application – applikationsweite Vorgaben
  • Modul
  • Class
partiell umgesetzt.
Sehen wir uns zu Beginn den Producer an.

image

 Hier gibt es zwei Besonderheiten, die Annotation @CDIRessourceKey und die Annotation @CDIFileBased

@CDIRessourceKey:
Mit dieser Annotation wird der RessourcenKey übergeben anhand die Auflösung erfolgen soll.
Das ist noch analog zu der normalen Verwendung messages.getString("greetings").  Innerhalb der Produces-Methode wird
auf die Annotation geprüft und der RessourcenKey extrahiert.

@CDIFileBased:
Diese Annotation deklariert die PropertyRegistryService Instanz. Das Interface selbst hat nur eine Methode.
public String getRessourceForKey(String ressourceKey);
Versucht der CDI-Container eine Instanz zu erzeugen, sucht er nach einer passenden Producer Methode.
Diese findet er in der Klasse  PropertyRegistryServiceProducer   die aus lediglich einer Methode besteht und eine Instanz von

FileBasedPropertyRegistryService erzeugt. Hier können umgebungsspezifische Parameter angewendet werden.
image

Innerhalb der Klasse FileBasedPropertyRegistryService befinden sich dann die einzelnen Registries für die jeweiligen Level die man zur Verfügung stellen möchte. Die Implemenntierung der Methode
public String getRessourceForKey(String ressourceKey)
gibt die Reihenfolge der Auflösung vor.  An dieser Stelle kann man auch ein Regelwerk hinterlegen, das sich an die derzeitige Systemumgebung anpasst…

image


Die Registries selbst sind sehr einfach gehalten. Es handelt sich hier um eine file-based – Implementierung.
Denkbar ist natürlich auch der Zugriff auf andere Medien wie Datenbank, Webservice,…

image

Zu erwähnen ist, dass diese Implementierung mindestens immer mit einer leeren dummy – Propertiesdatei
initialisiert wird, wenn keine konkrete gefunden wird.
Sieht man sich die Gesamtimplementierung an, handelt es sich um eine sehr überschaubare Anzahl Klassen.

image

Der Vollständigkeit halber noch die UML-Diagramme:
image



image


image