1 de nov de 2012

Internacionalização


Essa é uma dica para quem quer construir um aplicativo “poliglota”. Vamos fazer um utilitário bem simples que pode ser usado na internacionalização de aplicações em Java.

Abaixo estão as classes que servirão de suporte para construir o utilitário:

java.util.Locale
É composto de duas informações básicas: idioma e/ou país. Ex.: pt_BR (português, Brasil), en_US (Inglês, Estados Unidos). O idioma sempre em letras minúscula,s seguidos de _ (undeline) e do país em letras maiúsculas, sendo o segundo não obrigatório.

java.util.ResourceBundle
Classe responsável por fazer a leitura do arquivo onde estarão nossos termos e mensagens internacionalizadas.

java.text.MessageFormat
Essa classe vai auxiliar na formatação das mensagens antes de serem apresentadas ao usuário.

Nossa aplicação vai suportar 3 idiomas: inglês, português do Brasil e espanhol. Assumindo que nossa linguagem padrão será o inglês, portanto a aplicação sempre vai exibir os termos em inglês, caso o Locale seja diferente de “pt_BR” ou “es”.

Aqui estão os 3 arquivos de properties onde estarão nossos termos internacionalizados: messages.properties (inglês), messages_es (espanhol) e messages_pt_BR (português do Brasil).

messages.properties
message.title=Internationalization
message.hello=What`s up {0}?
message.goodbye=See ya!

messages_es.properties
message.title=Internacionalización
message.hello=¿Qué pasa {0}?
message.goodbye=¡Hasta la vista!

messages_pt_BR.properties
message.title=Internalionalização
message.hello=E ae {0}, blz?
message.goodbye=Falow!


Boa prática: Criar um enumerator que representa nosso arquivo de properties com todas as suas chaves.
package com.internacionalizacaoexemplo;

public enum MessageEnum {
    
    TITLE("message.title"),
    HELLO("message.hello"),
    GOODBYE("message.goodbye");
    
    private String prop;

    private MessageEnum(String prop) {
        this.prop = prop;
    }

    public String getProp() {
        return prop;
    }    
    
}

ResourceMessages: nossa classe que irá retornar as mensagens internacionalizadas
package com.internacionalizacaoexemplo;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

public class ResourceMessages {
    
    private static final String BUNDLE_NAME = "messages";
    
    public static String getMessage(MessageEnum messageEnum, Locale locale, Object... args ){
        ResourceBundle resourceBundle = null;
        
        if(locale!=null)
            resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME, locale);
        else
            resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
        
        String message = null;
        if(resourceBundle!=null){
            message = resourceBundle.getString(messageEnum.getProp());
            if(message!=null && args.length > 0)
                message = MessageFormat.format(message, args);
        }            
        return message;
    }
    
}


Abaixo uma classe para testarmos o ResourceMessages:
package com.internacionalizacaoexemplo;

import java.util.Locale;

public class App 
{
    public static void main( String[] args ){
        
        Locale.setDefault(Locale.ENGLISH);
        
        Locale pt_BR = new Locale("pt", "BR");
        System.out.println("-------------------------------------------------------");
        System.out.println(pt_BR);        
        System.out.println(ResourceMessages.getMessage(MessageEnum.TITLE, pt_BR));
        System.out.println(ResourceMessages.getMessage(MessageEnum.HELLO, pt_BR, "João"));
        System.out.println(ResourceMessages.getMessage(MessageEnum.GOODBYE, pt_BR));        
        
        Locale es_AR = new Locale("es", "AR");
        System.out.println("-------------------------------------------------------");
        System.out.println(es_AR);        
        System.out.println(ResourceMessages.getMessage(MessageEnum.TITLE, es_AR));
        System.out.println(ResourceMessages.getMessage(MessageEnum.HELLO, es_AR, "Juan"));
        System.out.println(ResourceMessages.getMessage(MessageEnum.GOODBYE, es_AR));        
                
        Locale en_US = Locale.US;
        System.out.println("-------------------------------------------------------");
        System.out.println(en_US);        
        System.out.println(ResourceMessages.getMessage(MessageEnum.TITLE, en_US));
        System.out.println(ResourceMessages.getMessage(MessageEnum.HELLO, en_US, "John"));
        System.out.println(ResourceMessages.getMessage(MessageEnum.GOODBYE, en_US));        
                
        Locale chinese = Locale.CHINESE;
        System.out.println("-------------------------------------------------------");
        System.out.println(chinese);        
        System.out.println(ResourceMessages.getMessage(MessageEnum.TITLE, chinese));
        System.out.println(ResourceMessages.getMessage(MessageEnum.HELLO, chinese, "Chin-chan"));
        System.out.println(ResourceMessages.getMessage(MessageEnum.GOODBYE, chinese));        
        
    }
}

Saída:
-------------------------------------------------------
pt_BR
Internalionalização
E ae João, blz?
Falow!
-------------------------------------------------------
es_AR
Internacionalización
¿Qué pasa Juan?
¡Hasta la vista!
-------------------------------------------------------
en_US
Internationalization
What`s up John?
See ya!
-------------------------------------------------------
zh
Internationalization
What`s up Chin-chan?
See ya!


Código fonte: http://depositfiles.com/files/qwrcxn0eq

This is Java! Is we on the tape... traduzindo, é nóis na fita!

2 comentários:

  1. AH VÁ RAPÁ....EU CONHEÇO ESSE FDP QUE FEZ ESSE BANNER...DÁ HORA...FÉÉÉLA. SUCESSO PRA VCS!!!!

    ResponderExcluir
  2. Para projetos de localização usando arquivos .properties, eu recomendo a plataforma de tradução do softwares https://poeditor.com

    ResponderExcluir