ResourceBundle auf Basis mehrerer Properties

Das übliche Verfahren, lokalisierte Meldungen zu erzeugen, ist die – meist implizite – Nutzung von PropertyResourceBundle. So bezieht bspw. Bean Validation seine Meldungen aus einem Resource Bundle mit Namen ValidationMessages. Dieses materialisiert sich üblicherweise aus Classpath-Ressourcen namens ValidationMessages.properties, ValidationMessages_de.properties etc.

Problematisch ist bei diesem Verfahren, dass z. B. nur eine Datei namens ValidationMessages.properties verwendet wird, auch wenn es davon mehrere im Classpath gibt. Damit ist leider der Weg verbaut, in einer Utility-Bibliothek bspw. Bean Validation Constraints inkl. der zugehörigen Meldungen auf einfache Weise zu definieren:

– Anwendung definiert Validierungsmeldungen als Classpath-Ressource-Bundle „ValidationMessages“ (1),
– von der Anwendung genutzte Bibliothek enthält ebenfalls ein Classpath-Ressource-Bundle „ValidationMessages“ (2).
– Validierungsfehler nutzen die Meldungen aus (1), aber nicht (2)!

Abhilfe ist hier leicht zu schaffen: Statt der impliziten Nutzung eines PropertyResourceBundle lässt sich eine Lokalisierung von Texten auch durch explizite Bereitstellung eines Resource-Bundles in Form passend benannter Klassen erreichen, d. h. im Beispielszenario können die Klassen ValidationMessages, ValidationMessages_de etc. zur Verfügung gestellt werden (alle im Default-Paket). Die Klassen müssen von java.util.ResourceBundle abgeleitet sein. In ihrem Konstruktor suchen sie nach allen passenden Classpath-Ressourcen und bauen damit einen interne Lookup-Tabelle auf. Sinnigerweise implementiert man dieses Verhalten in einer entsprechenden Basisklasse:

public class ValidationMessages extends MultiPropertiesResourceBundle
 {
 }

public class ValidationMessages_de extends MultiPropertiesResourceBundle
 {
 }

...

public class MultiPropertiesResourceBundle extends ResourceBundle
 {
      private Map messageMap = new HashMap();
 }

public MultiPropertiesResourceBundle()
  {
      loadProperties(this.getClass().getName().replace('.', '/') + ".properties");
  }

public MultiPropertiesResourceBundle(String bundleName)
  {
      loadProperties(bundleName + ".properties");
  }

private void loadProperties(String resourceName)
  {
     try
      {
      Enumeration found = Thread.currentThread().getContextClassLoader().getResources(resourceName);
          while (found.hasMoreElements())
          {
              URL url = found.nextElement();
              loadMessages(url);
          }
      }
      catch (IOException e)
      {
      // ignore
      }
  }

private void loadMessages(URL url)
  {
      Reader reader = null;
      try
      {
          reader = new InputStreamReader(url.openStream(), "UTF-8");

        Properties prop = new Properties();
          prop.load(reader);

        for (Entry entry : prop.entrySet())
          {
              String key = (String) entry.getKey();
              if (!this.messageMap.containsKey(key))
              {
                  String value = (String) entry.getValue();
                  this.messageMap.put(key, value);
              }
          }
      }
      catch (IOException e)
      {
          // ignore
      }
  finally
  {
      try
      {
          reader.close();
      }
      catch (Exception e)
      {
          // ignore
      }
  }
  }

@Override
  public Enumeration getKeys()
  {
      ResourceBundle parent = this.parent;
      return new ResourceBundleEnumeration(this.messageMap.keySet(), (parent != null) ? parent.getKeys() : null);
  }

@Override
  protected Object handleGetObject(String key)
  {
      return this.messageMap.get(key);
  }
 }
Advertisements

Über Dirk Weil
Dirk Weil ist seit 1998 als Berater im Bereich Java tätig. Als Geschäftsführer der GEDOPLAN GmbH in Bielefeld ist er für die Konzeption und Realisierung von Informationssystemen auf Basis von Java EE verantwortlich. Seine langjährige Erfahrung in der Entwicklung anspruchsvoller Unternehmenslösungen machen ihn zu einem kompetenten Ansprechpartner und anerkannten Experten auf dem Gebiet Java EE. Er ist Autor in Fachmagazinen, hält Vorträge und leitet Seminare und Workshops aus einem eigenen Java-Curriculum.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: