Per chi è l'articolo

In primo luogo questo articolo è rivolto a sviluppatori Java che stanno sviluppando i componenti con supporto di internalization. L'articolo sarà comunque utile per tutti coloro che lavorano con Java e stanno usando i file di risorse e le classi di tipo java.util.ResourceBundle e java.text.Format.

L'esempio è usato per proiezione

Come esempio sarà usata l'applicazione nel trial "Internationalization" della guida "The Java Tutorial" [1]. Ne è possibile trovare all'indirizzo http://java.sun.com/docs/books/tutorial/i18n/intro/after.html. L'applicazione fa supporto per inglese, francese e tedesco. In particolare, tutti i messaggi testuali devono essere nella lingua locale dell'ambiente in cui si opera.

La soluzione di Sun

Sun in questo caso fa così:

Crea un .properties file per ogni locale di supporto.

Aggiunge a ognuno dei file la riga con la stessa chiave della risorsa. Ad esempio "greetings" con il testo nel propria lingua. Cioè, per la versione francese, il file sarà:

## MessagesBundle_fr_FR.properties

greetings = Bonjour.

farewell = Au revoir.

inquiry = Comment allez-vous?

E per la versione inglese:

## MessagesBundle_us_US.properties

greetings = Hello.

farewell = Goodbye.

inquiry = How are you?

Scrive il codice del tipo:

// Inizializzazione del manager di risorse

Locale currentLocale;

ResourceBundle messages;

currentLocale = new Locale(language, country);

messages = ResourceBundle.getBundle("MessagesBundle",

currentLocale);

// Manipolazione delle risorse

System.out.println(messages.getString("greetings"));

System.out.println(messages.getString("inquiry"));

System.out.println(messages.getString("farewell"));

Sembra che vada tutto bene, ma vediamo il codice più attentamente:

Se si cambia la chiave della risorsa o si sbaglia la scrittura del nome in sorgente, il compilatore non darà nessun errore perché nel sorgente quel nome è scritto come una stringa.

Spesso le risorse testuali sono modelli dei messaggi con alcuni parametri. Il fatto che i modelli siano dichiarati in altro file crea il rischio supplementare che il numero e la sequenza dei parametri, nel prossimo uso del modello, non saranno coordinati.

jResWrap come la possibilità di risoluzione dei problemi di questo tipo

Proprio per risolvere questi problemi era stato creato lo strumento jResWrap che genera le classi-involucri per risorse testuali dei file di tipo .properties. Le classi-involucri danno la possibilità allo sviluppatore di lavorare con le risorse in modo molto più comodo. Per il famoso esempio è abbastanza scrivere:

// Inizializzazione del manager di risorse

Locale currentLocale;

ResourceBundle messages;

currentLocale = new Locale(language, country);

messages = ResourceBundle.getBundle("MessagesBundle",

currentLocale);

// Creazione della classe-involucro

_MessagesBundle messagesBundle;

messagesBundle = new _MessagesBundle( messages );

// Manipolazione delle risorse

System.out.println( messagesBundle.greetings() );

System.out.println( messagesBundle.inquiry() );

System.out.println( messagesBundle.farewell() );

Che cosa è cambiato?

Se la chiave sarà modificata ora siamo in sicurezza in quanto il compilatore darà un errore perché il classe-copertina non avrà il metodo greetings.

Se cambiamo anche il numero di parametri nel modello testuale, non abbiamo nessun problema. Il compilatore di nuovo darà un errore perché la segnatura del metodo sarà cambiata.

Facendo le modifiche ora è possibile vedere la guida per ogni parametro per essere sicuro che la sequenza è giusta.

Come creare l'involucro

jResWrap è lo strumento di linea di comando che è controllato con parametri. Tornando al nostro esempio vediamo che il nome di package del programma è di default (ROOT), i file del progetto sono nella cartella "esempio" ed i file delle risorse si chiamano "MessagesBundle.properties"*. Allora per lanciare lo strumento è sufficiente digitare:

per Windows

%JRESWRAP%\bin\jreswrap.bat ROOT "esempio" "MessageBundle"

per Linux e Solaris

$JRESWRAP/bin/jreswrap.sh ROOT "esempio" "MessageBundle"

Quando lo strumento finirà di lavorare nella cartella dei sorgenti di progetto, sarà creato il file con il nome "_MessagesBundle.java" nel quale sarà definita la classe con stesso nome e nello stesso package di tutto il progetto.

Se per il build del tuo progetto usi ant è meglio aggiungere nello script qualcosa simile a:

<exec executable="${env.JRESWRAP}/bin/jreswrap" >
  <arg value="ROOT"/>
  <arg value="${dir.src}"/>
  <arg value="MessageBundle"/>
</exec>

Che cosa c'è intorno

La classe generata contiene:

Il costruttore nel quale si inizializza il campo privato di tipo java.util.ResourceBundle.

I read-only campi statici con i nomi delle chiave del file di risorse.

I metodi tornano i valori testuali delle risorse.

Se la risorsa testuale contiene parametri, la segnatura del metodo avrà lo stesso numero di parametri. Per ciascuno di loro sarà aggiunto anche un commentario. Inoltre dopo aver scaricato la risorsa dal file sarà richiamato il metodo java.text.Format.format, che prepara la versione finale del messaggio.

Conclusione

Allora, se hai deciso di usare lo strumento dovresti fare i seguenti passi:

Aggiungere il richiamo dello strumento jResWrap allo script utilizzato per automatizzare il build del progetto.

Recompile il progetto.

Aggiungere il file dell'involucro alla lista dei file del progetto.

Creare un oggetto della classe-involucro.

Chiamare il proprio metodo per ritirare la risorsa testuale necessaria.

Sorgenti

Il progetto Java Resource Wrapper si sta sviluppando come un strumento con sorgenti aperte (open source). Lo strumento è possibile scaricarlo gratuitamente nel seguente indirizzo: http://cvs.sourceforge.net/viewcvs.py/jreswrap/

Bibliografia

  • [1] Dale Green - "*Trail: Internationalization*", The Java Tutorial, 2004