Crear Subclases de Excepciones Independientes de la Localidad

Si queremos crear un subclase de Exception cuando necesitamos manejar errores específicos de nuestras aplicaciones, podemos crear nuestras subclases independientes de la Localidad sobrescribiendo su método getLocalizedMessage. Cada método que sobrescribamos debería aislar el mensaje que devuelve en un ResourceBundle. Esto permitirá que el mensaje sea traducido a varios idiomas durante la localización.

En el siguiente ejemplo, veremos cómo crear una subclase de Exception que muestra un mensaje independiente de la Localidad. El código fuente de este programa está en estos dos ficheros: OverLimitException.java y Account.java.

El programa Account simula una cuenta de crédito. Si este programa se excede el límite de crédito, recupera un mensaje localizado desde un ResourceBundle llamado ExceptionBundle, y luego muestra el mensaje. En el fichero ExceptionBundle_en_US.properties, hemos especificado este mensaje:

pattern =  Negative balance of {0,number,currency} is not allowed.
El programa Account recupera el mensaje con el método getLocalizedMessage, que hemos implementado en una subclase de Exception llamada OverLimitException. El método getLocalizedMessage acepta un objeto Locale como parámetro. Especificamos la Localidad cuando recuperamos el patrón del mensaje desde el ResourceBundle, y también cuando definimos el objeto MessageFormat. Por lo tanto, nuestra clase OverLimitException es sensible a la Localidad:
public class OverLimitException extends Exception {

   private double detail;

   public OverLimitException (double amount) {
       detail = amount;
   }

   public String getMessage() {
      return getLocalizedMessage(Locale.getDefault());
   }

   public String getLocalizedMessage(Locale currentLocale) {
      ResourceBundle messages =
         ResourceBundle.getBundle("ExceptionBundle",currentLocale);
      Object[] messageArguments = {new Float(detail)};
      MessageFormat formatter = new MessageFormat("");
      formatter.setLocale(currentLocale);
      formatter.applyPattern(messages.getString("pattern"));
      return formatter.format(messageArguments);
   }
}
En la clase Account, el método withdraw lanza un OverLimitException si el nuevo balance excede el límite de crédito. En el siguiente código, observa que hemos pasado el parámetro value al constructor OverLimitException en la sentencia throw. El constructor asigna este parámetro al campo detail de la clase OverLimitException. El método getLocalizedMessage inserta una representación String del campo detail en el mensaje devuelto. El método withdraw es el siguiente:
public void withdraw(double amount) throws OverLimitException {
   double value = balance - amount;
   if (value < creditLimit) {
     throw new OverLimitException(value);
   }
   else {
      balance = value;
   }
}
En el método main de la clase Account, llamamos al método withdraw y captura el OverLimitException siempre que se lance. La clausula catch imprime el String devuelto por getLocalizedMessage. Aquí tienes el método main:
static public void main(String[] args) {

   Locale[] locales = {
      new Locale("en","US"),
      new Locale("de","DE")
   };

   Account credit = new Account();
   credit.deposit(20.00f);

   for (int k = 0; k < locales.length; k++) {
      try {
         credit.withdraw(1000.00f);
      }
      catch (OverLimitException e) {
         System.out.println("Locale: " + locales[k].toString());
         System.out.println(e.getLocalizedMessage(locales[k]));
      }
   } // for
}
El programa Account muestra dos mensajes localizados. No sólo el texto se muestra en el idioma correcto, si no que también el formato de moneda es el adecuado para cada Localidad.:
% java Account

Locale: en_US
Negative balance of ($980.00) is not allowed.

Locale: de_DE
Ihr Konto um -980,00 DM zu überziehen ist nicht gestattet.

Ozito