viernes, 5 de agosto de 2011

Internacionalización a lenguajes con diferentes formas plurales en Java


Java
Si desarrollamos una aplicación para diferentes lenguajes y por tanto necesitamos internacionalizarla es probable que tengamos que tener en cuenta el número de diferentes formas plurales que tengan esos lenguajes. El español tiene dos formas plurales o tipos de número (singular/1, plural/1+) pero otros lenguajes tienen más de dos formas plurales (nular/0, dual/2, trial/3, paucal/grupo reducido). Java da soporte a esta funcionalidad a través de la clase ChioceFormat aunque nos requerirá un poco más de trabajo formatear cada mensaje.

A través de la clase ChoiceFormat elegimos la cadena con la forma plural correcta, posteriormente tal vez debamos hacer sustituciones en el mensaje con un MessageFormat.

En el javadoc de ChoiceFormat viene explicado como construir un patrón para posteriormente con la cantidad de elementos seleccionar la forma plural correcta.

Estos dos pasos quedarían así:

import java.text.ChoiceFormat;
import java.text.MessageFormat;

public class Test {
    public static void main(String[] args) {
	// Construir el ChoiceFormat
        ChoiceFormat cf = new ChoiceFormat("0#Hay {0} elementos.|1#Hay {0} elemento.|1<Hay {0} elementos.");
        String m = null;
        double n = 0;

        // Obtener la forma plural
        n = -3;
        m = cf.format(n)

        // Formatear
        System.out.println(MessageFormat.format(m, n));

        n = 0.5;
        m = cf.format(n)
        System.out.println(MessageFormat.format(m, n));
        
        n = 1;
        m = cf.format(n)
        System.out.println(MessageFormat.format(m, n));

        n = 2.5;
        m = cf.format(n)
        System.out.println(MessageFormat.format(m, n));

        n = 3;
        m = cf.format(n)
        System.out.println(MessageFormat.format(m, n));
    }
}

El resultado de este programa es:

Hay -3 elementos.
Hay 0,5 elementos.
Hay 1 elemento.
Hay 2,5 elementos.
Hay 3 elementos.

Si el String que se le pasa al ChoiceFormat viniese de un archivo .properties con los mensajes de cada idioma podríamos soportar varias formas plurales cambiando los límites en el mensaje localizado. En español tendríamos un literal en un properties tal que:

elementos=0#Hay cero elementos.|1#Hay un elemento.|1<Hay algo más de un elemento.

Pero en otro idioma podríamos tener esto según las diferentes formas plurales de ese idioma:

elementos=0#Hay menos de un elemento.|1#Hay un elemento.|1<Hay algo más de un elemento.|2#Hay dos elementos||2#Hay algo más de dos elementos.|3#Hay tres o más elementos.

Hay menos de un elemento.
Hay menos de un elemento.
Hay un elemento.
Hay algo más de dos elementos.
Hay tres o más elementos.


Referencia:
http://download.oracle.com/javase/7/docs/api/java/text/ChoiceFormat.html
http://download.oracle.com/javase/7/docs/api/java/text/MessageFormat.html