El API JAXB

Este cap�tulo muestra c�mo utilizar extensi�n para a�adir funcionalidades espec�ficas de la aplicacion a nuestra aplicaci�n JAXB. Continuaremos con el CheckbookApp que creamos en el cap�tulo anterior. En este cap�tulo, crearemos una nueva clase, llamada CheckbookBalance. Esta nueva clase extender� la clase Checkbook generada y contendr� un m�todo que a�ada las transacciones al checkbook y calcule el nuevo balance. La clase CheckbookApp llama a este nuevo m�todo para a�adir las transacciones de Marzo y Abril (representadas por los �rboles de contenido que creamos en el cap�tulo anterior) al checkbook. En este cap�tulo, trabajaremos con el documento checkbook.xml, que representa el libro de cheques. La lista de transacciones y el balance de la cuenta.

.�El Documetno XML de Ejemplo: checkbook.xml

El documento de checkbook.xml define un checkbook, que contiene un conjunto de transacciones y un balance, as� que en vez de definir transactions como el elemento ra�z, este documento define el elemento checkbook como el elemento ra�z, que contiene la lista de transacciones y el balance:

<?xml version="1.0" encoding="US-ASCII"?> 
<checkbook> 
    <transactions> 
        <deposit category=salary> 
            <date>02-09-2001</date> 
            <name>Me</name> 
            <amount>2500.00</amount> 
        </deposit> 
        <check number="90" category="other"> 
            <date>02-12-2001</date> 
            <name>My Local Bookstore</name> 
            <amount>34.95</amount>.
            <pending/> 
            <memo>Dukes Book</memo> 
        </check> 
        <check number="91" category="rent"> 
            <date>02-28-2001</date> 
            <name>Landlord</name> 
            <amount>1500.00</amount> 
            <void/> 
            <memo>February</memo> 
        </check> 
    </transactions> 
    <balance>50000.00</balance> 
</checkbook>

Observa que checkbook s�lo tiene las transacciones de Febrero. Este cap�tulo mostrar� c�mo a�adir las transacciones de Marzo y de Abril al checkbook y poner al d�a el balance. El fichero checkbook.xml tambi�n est� situado en el directorio examples/checkbook de la instalaci�n.

.�Configurar la Clase CheckbookBalance

Para crear la clase CheckbookBalance:

  1. Creamos un fichero llamado CheckbookBalance.java.
  2. Importamos estos paquetes:
    import java.io.*;
    import java.util.*;
    import java.math.*;
    
  3. Declaramos la clase CheckbookBalance para que extienda Checkbook:
    public class CheckbookBalance extends Checkbook {
    }
    
  4. Dentro de CheckbookBalance, creamos el m�todo balanceCheckbook:
    public class CheckbookBalance extends Checkbook {
        void balanceCheckbook(Transactions trans) throws Exception {
        }
    }
    

    Este m�todo contendr� todo el c�digo para agregar transacciones al checkbook y para calcular el nuevo balance. La clase CheckbookApp pasar� la lista completa de transacciones que creamos en la secci�n anterior al m�todo balanceCheckbook.

.�Extender las clases Derivadas

En el cap�tulo Construir Representaciones de Datos, aprendimos c�mo utilizar directamente las clases derivadas. Otra manera de usar las clases derivadas es con la extensi�n. La extensi�n implica la subclasificaci�n de una clase derivada para proporcionar funciones espec�ficas. Esta secci�n explica la extensi�n mostrando c�mo balancear el checkbook y agregar las entradas de transacciones al checkbook.

.�Desempaquetar

Antes de que podamos realizar los c�lculos, necesitamos desempaquetar el fichero que contiene las transacciones en un �rbol de contenido, como hizimos en la secci�n Desempaquetamiento del cap�tulo anterior. Sin embargo, este vez estamos extendiendo checkbook en vez de utilizarlo directamente, lo que significa que desempaquetamos un objeto CheckbookBalance, no un objeto Checkbook. Si no especificamos que CheckbookBalance debe ser desempaquetado, el proceso de desempaquetamiento devuelve un objeto Checkbook, no un objeto CheckbookBalance. Para solucionar este problema, necesitamos registrar CheckbookBalance con un Dispatcher.

.�Despachar

Un dispatcher asocia nombres de elementos con nombres de clases y nombres de sublases con nombres de clases. El proceso de desempaquetamiento comienza con la llamada de los m�todos unmarshal de un dispatcher. Un dispatcher por defecto desempaqueta contenido XML XML en ejemplares de las clases generadas. Para nuestro ejemplo, esto significa que el m�todo unmarshal devolver�a un checkbook, no un CheckbookBalance. Para devolver un CheckbookBalance, necesitamos registrar CheckbookBalance con el Dispatcher. Para hacer esto:

  1. En la parte superior de CheckbookApp.java , inicializamos un objeto CheckbookBalance:
    public static CheckbookBalance chBook = new CheckbookBalance();
    
  2. Creamos un nuevo m�todo en CheckbookApp.java llamado unmarshalSubclass:
    public static void unmarshalSubclass() throws Exception{}
    
  3. En este nuevo m�todo, adquirimos el Dispatcher por defecto de Checkbook:
    Dispatcher d = Checkbook.newDispatcher();
    
  4. Registramos CheckbookBalance con el Dispatcher devuelto:
    d.register(Checkbook.class, CheckbookBalance.class);
    

    Este m�todo registra la subclase CheckbookBalance con el Dispatcher para que pueda desempaquetar un CheckbookBalance en lugar de un Checkbook.

  5. Llamamos a unmarshalSubclass desde el m�todo main:
    unmarshalSubclass();
    

.�Desempaquetar las Subclases

Como registramos CheckbookBalance con un Dispatcher, necesitamos llamar al m�todo unmarshal del dispatcher, no al m�todo unmarshal del objeto CheckbookBalance. Para desempaquetar CheckbookBalance:

  1. En el m�todo unmarshalSubclass, leemos checkbook.xml en un FileInputStream:
    File checkbookNew = new File(checkbook.xml);
    FileInputStream fNewIn = new FileInputStream(checkbookNew);
    
  2. Forzamos el objeto devuelto por el m�todo unmarshal a un objeto CheckbookBalance:
    try{
        chBook = (CheckbookBalance)(d.unmarshal(fNewIn));
    } 
    finally {
        fNewIn.close();
    }
    

La siguiente secci�n demuestra c�mo implementar los c�lculos del balance del libro de cheques en CheckbookBalance.java.

.�A�adir Funcionalidad

El fichero CheckbookBalance.java s�lo contiene un m�todo: balanceCheckbook. Esta secci�n muestra c�mo implementar balanceCheckbook para calcular el nuevo balance bas�ndose en el balance del m�s anterior y a�adiendo las transacciones de Marzo y Abril. Para implementar el m�todo balanceCheckbook en la clase CheckbookBalance:

  1. Obtenemos el balance actual grabado en nuestro checkbook:
    BigDecimal balance = this.getBalance();
    
  2. Obtenemos la lista de entradas de los objetos Transactions qu se pasa a este m�todo:
    List tEntries = trans.getEntries();
    
  3. Inicializamos un BigDecimal para guardar la cantidad de cada transaci�n:
    BigDecimal amt;
    
  4. Creamos un bucle para iterar a trav�s de la lista de transaciones y obtener la cuant�a de cada una:
    for (ListIterator i = tEntries.listIterator(); i.hasNext(); ) {
    Entry entry = (Entry)i.next();
    amt = entry.getAmount();
    
  5. Si la entrada es un Deposit, a�adimos la cuant�a del dep�sito al balance del checkbook; de otro modo, restamos la cuant�a de la transaci�n al balance:
    if (entry instanceof Deposit){
        balance = balance.add(amt);
    } 
    else {
        balance = balance.subtract(amt);
    }
    
  6. despu�s de recalcular el balance basado en la transacci�n, a�adimos la transaci�n a la lista de transaciones del checkbook:
    this.getTransactions().getEntries().add(entry);
    }
    
  7. Despu�s de haber iterado por la lista de transaciones, chequemos si el balance es negativo. Si es as�, avisamos al usuario de que est� en n�meros rojos:
    if(balance.compareTo(new BigDecimal(0.00)) == -1){
        System.out.println("You are overdrawn.");
    }
    
  8. Imprimimos el nuevo balance y seleccionamos el balance del checkbook al nuevo balance:
    System.out.println("Your balance is: "+balance);
    this.setBalance(balance);
    

La siguiente secci�n muestra c�mo invocar la nueva funcionalidad en CheckbookBalance desde CheckbookApp.java.

.�Usar las Nuevas Funcionalidades en Nuestra Aplicaci�n

Esta secci�n muestra c�mo utilizar el m�todo balanceCheckbook de CheckbookApp para balancear checkbook y para a�adir las transacciones a de Marzo y Abril al checkbook. La clase CheckbookBalance est� escrit� de una forma gen�rica de modo que pueda tomar cualquier objeto transactions y a�adir las transacciones a un checkbook y calcular el nuevo balance. Todo lo que necesitamos hacer desde neustra aplicaci�n es llamar al m�todo balanceCheckbook con un objeto Transactions particular y empaquetar el resultado en un nuevo fichero checkbook. Para poner al d�a el checkbook con las nuevas transacciones y balancear:

  1. En el m�todo main de la clase CheckbookApp, llamamos al m�todo balanceCheckbook con el objeto marchTrans:
    chBook.balanceCheckbook(marchTrans);
    

    Este objeto contiene la lista de transaciones de Marzo y Abril que creamos en la secci�n A�adir �rboles de Contenido. El objeto chBook ahora contiene las transaciones y el balance actualizados.

  2. Creamos un nuevo m�todo en CheckbookApp llamado validateAndMarshalCheckbook:
    public static void validateAndMarshalCheckbook() throws Exception {}
    
  3. Como editamos el �rbol de contenido del checkbook, realizamos la validaci�n sobre chBook dentro del nuevo m�todo que acabamos de crear:
    chBook.validate();
    
  4. Creamos un nuevo fichero XML para el checkbook actualizado:
    File checkbook_new = new File("checkbook_new.xml");
    FileOutputStream fCOut = new FileOutputStream(checkbook_new);
    
  5. Empaquetamos el checkbook actualizado en el nuevo fichero XML:
    try {
        chBook.marshal(fCOut);
    } 
    finally {
        fCOut.close();
    }
    
  6. Llamamos a validateAndMarshalCheckbook desde el m�todo main de CheckbookApp:
    validateAndMarshalCheckbook();
    
  7. Grabamos CheckbookBalance.java y CheckbookApp.java y recompilamos:
    javac *.java
    
  8. Ejecutamos de nuevo CheckbookApp:
    java CheckbookApp
    

Nuestro fichero checkbook_new.xml tiene un balance actualizado de $48065.72 y contiene nuestras transaciones de Febrero, Marzo y Abril.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO