miércoles, abril 27, 2011

Creacion De Archivos II (Archivos para Batch, con Properties)

Retomando el post anterior, una forma de no recompilar nuestra aplicacion cuando cambien las longitudes de los campos puede ser utilizando archivos properties.

1.- por tanto hay que crear un archivo properties el cual contenga las restricciones

nombreL = 10
apellidoL = 20
edadL = 2
telefonoL = 8 


#espacio (Espa)
nombreS =Espa
apellidoS =Espa
edadS = 0
telefonoS =Espa 

2.- modificamos el constructor de nuestra clase Bean

creamos una variable properties y en el contructor

Properties properties;

public Bean() {
        properties = new Properties();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("rutaProperties"+File.separator+"propiedades.properties");
            properties.load(fis);
        } catch (FileNotFoundException e) {
            System.out.println("Archivo de configuracion no encontrado ");           
        } catch (IOException e) {
 
            System.out.println("No se pudo leer el archivo");               
        }

}

3.- modificamos nuestros metodos set, solo pondre el ejemplo de 1

public void setNombre(String nombre) {
        if(nombre==null){
            nombre = "          ";
        }
        else if(nombre.length()<Integer.parseInt ( properties.getProperty(
nombreL ) ) ){
            do{

                 if(properties.getProperty( nombreL ) .equals("Espa")){
                        nombre = nombre.concat(" ");

                 }else{
                        nombre = properties.getProperty( nombreL );
                 }
            }while(nombre.length()<=
Integer.parseInt ( properties.getProperty( nombreL ) ) );
        }

        if(nombre.length()>Integer.parseInt ( properties.getProperty( nombreL ) ) ){
            nombre = nombre.substring(0,
Integer.parseInt ( properties.getProperty( nombreL ) ) );
        }
        this.nombre = nombre;
    }


NOTA: SI OBSERVAMOS AHORA LA INFORMACION LA TOMAMOS DEL PROPERTIES, Y EL SEGUNDO ELSE IF, CAMBIA A IF, ESTO POR QUE TAL VES NUESTRO SEPARADOR QUE HEMOS CREADO ES DE MAS DE 1 CARACTER

YA HA CAMBIADO LA APLICACION, YA NO TENEMOS QUE RECOMPILAR LA APLICACION PARA CUANDO CAMBIAN LAS LONGITUDES, PERO AUN SIGUE SIN GUSTARME, ADEMAS SI DEPENDEMOS DE OTRAS REGLAS COMO ALINEAR A ALGUN LADO, PS SALE LO MISMO

SEGUIREMOS MODIFICANDO EL CODIGO...





Creacion De Archivos I (Archivos para Batch)

Algunas veces nos hemos visto obligados a crear archivos con informacion provenientemente de nuestra bd, para enviarlo a otro sistema el cual procesara esa informacion normalmente cargando la informacion en otra bd, esto es muy comun entre los bancos

los bancos o para los bancos se crean archivos con los clientes y sus pagos o sus cargos, estos se envian y procesan para realizar los cargos sobre nuestras tdc o tdd (Domiciliacion)

estos archivos tienen ciertas caracteristicas como: alinear los nombres a la derecha, rellenar de espacios un texto, longitudes fijas, rellenar con caracteres un texto, colocar encabesados etc...


A continuacion veremos algunas formas de realizar estos benditos archivos


1.- supongamos una clase que se dedicara a crear un archivo y escribir sobre el.


public class Escritura {
    String ruta;
    String archivo;
    private FileWriter fichero;
    private PrintWriter pw;

    public void abrirArchivo() {
        try {
            fichero = new FileWriter(ruta + File.separator + archivo);
            pw = new PrintWriter(fichero);
        } catch (IOException e) {
            System.out.println("Error al abrir archivo");
        }
    }

    public void cerrarArchivo() {

        try {
            if (fichero != null) {
                fichero.close();
            }
        } catch (IOException e) {
            System.out.println("error al cerrar archivo");
        }
    }

    public void escribir(String texto) {
        if (fichero != null) {
            pw.println(texto);
        }else{
            System.out.println("El archivo no esta abierto");
        }
    }

}

2.- supongamos ahora una clase en la cual tendremos los datos que contendra el archivo a crear

class Bean{
   
    private String nombre;
    private String apellido;
    private String edad;
    private String telefono;


 // con sus metodos get y set



3.-  nos encontramos ahora un detalle, ese bean se tendra que escribir sobre un archivo, pero nuestra clase de escritura escribe String, por tanto tenemos que agrupar nuestros 4 datos en una sola variable que sera la que se escriba


public String toString(){
        return nombre + apellido + edad + telefono;
    }


4.- ahora tenemos algunas restricciones para crear nuestro archivo

- El nombre tiene que ser maximo de 10 caracteres, si es menor a 10, se llenaran las posiciones restantes con espacios
- El apellido tiene que ser maximo 20 caracteres, si es menor a 20, se llenaran las posiciones restantes con espacions
- La edad es maximo 2 caracteres, si la edad es menor a 10, se pondra un 0 a la izquierda: 8 años > 08
- El telefono es maximo 8 caracteres, rellenado con espacios

5.- para cumplir nuestras condiciones, modifiquemos nuestros metodos set 

public void setNombre(String nombre) {
        if(nombre==null){
            nombre = "          ";
        }
        else if(nombre.length()<10){
            do{
                nombre = nombre.concat(" ");
            }while(nombre.length()<=10);
        }else if(nombre.length()>10){
            nombre = nombre.substring(0,10);
        }
        this.nombre = nombre;
    }
    public void setApellido(String apellido) {
        if(apellido==null){
            apellido = "                    ";
        }
        else if(apellido.length()<20){
            do{
                apellido = apellido.concat(" ");
            }while(apellido.length()<=20);
        }else if(apellido.length()>20){
            apellido = apellido.substring(0,20);
        }       
        this.apellido = apellido;
    }
    public void setEdad(String edad) {
        if(edad==null){
            edad = "  ";
        }else if(edad.length()<2){
            edad = "0"+edad;
        }else if(edad.length()>2){
            edad = edad.substring(0,2);
        }           
        this.edad = edad;
    }
    public void setTelefono(String telefono) {
        if(telefono==null){
            telefono = "        ";
        }
        else if(telefono.length()<8){
            do{
                telefono = telefono.concat(" ");
            }while(telefono.length()<=8);
        }else if(telefono.length()>8){
            telefono = telefono.substring(0,8);
        }       
        this.telefono = telefono;
    }


NOTA: QUE TREMENDO CHOROTE NO ???? ( YA VEREMOS FORMAS SUPER SENSILLAS DE REALIZAR ESTO) 

6.- hay que crear una clase con su main, hacer instancia de las 2 clases anteriores, darles valores a sus variables 

public static void main(String args[]){
        Bean miBean = new Bean();
        Escritura miEscritura = new Escritura();
      
        miBean.setNombre("Ing. Fher");
        miBean.setApellido("Java - Limos . Blogspot");
        miBean.setEdad("23");
        miBean.setTelefono("12345678");
      
        miEscritura.archivo="JavaLimos.txt";
        miEscritura.ruta="D:";
      
        miEscritura.abrirArchivo();
        miEscritura.escribir(miBean.toString());
        miEscritura.cerrarArchivo();
    }


7.- al mandar escribir, llamamos al metodo toString que sobreescribimos


al final nuestro archivo quedaria algo como


Ing. Fher  Java - Limos . Blogs2312345678

8.- si se dan cuenta,  Java - Limos . Blogspot rebaso los 20 caracteres y fue cortado a Java - Limos . Blogs


ESTO ES MUY UTIL, PERO SI LAS LONGITUDES CAMBIAN, OBIAMENTE TENEMOS QUE RECOMPILAR NUESTRO PROGRAMA :(

lunes, abril 25, 2011

Primeros Pasos Con Spring II

La entrada anterior vimos como inyectar una clase a otra de una forma sensilla, ahora veamos que pasa si utilizamos Interfaces

1.- Hay que crear una interfaz


public interface Impresora{
           public void imprimirTexto(String elTexto);
 }

2.- Hagamos dos implementaciones de Impresora


public class ImpresoraPorPalabras implements Impresora{
          public void imprimirTexto(String elTexto){
                    String [ ] separadoEnPalabras = elTexto.split(" ");
                    int pal=1;

                    for(String palabra: separadoEnPalabras){
                              System.out.println(pal + " " + palabra); 
                               pal++;
                    }
          } 
}


public class ImpresoraPorLetras implements Impresora{
           public void imprimirTexto(String elTexto){
                     char [ ] letras = elTexto.toCharArray();
                     int let=1;
                     for(char letra: letras){
                               System.out.println( let + " " + letra );
                               let++;
                     }
           }
}

3.-  Creamos nuestra clase que llamara a alguna implementacion de Impresora

public class EnviaTextos{
           public Impresora miImpresora;
           public void setMiImpresora(Impresora miImpresora){
                     this.miImpresora = miImpresora;
           }
          public Impresora getMiImpresora(){
                     return miImpresora;

          }
          public void mandarTextos(){
                     getMiImpresora().imprimirTexto("Interfaces con Spring, solo en Java-Limos");
           }

}
 
4.-  En nuestro applicationContext.xml mapearemos las 3 clases


< bean class="ejemplos.spring.basico.interfaces.ImpresoraPorLetras" id="porLetras" / >


< bean class="ejemplos.spring.basico.interfaces.ImpresoraPorPalabras" id="porPalabras" / > 


< bean class="ejemplos.spring.basico.interfaces.EnviaTextos" id="enviaTextos" >
          <property name="miImpresora" ref="porPalabras"/>
< / bean >


5.- En nuestra clase Test hagamos instancia a EnviaTextos


public class Test{          public static void main( String[ ] args ) {                    BeanFactory fabricaDeBeans= new XmlBeanFactory(new ClassPathResource("/applicationContext.xml"));

                    EnviaTextos textos = (EnviaTextos)fabricaDeBeans.getBean(EnviaTextos.class);

                    textos.mandarTextos();       
    }
}


NOTA: En este caso si ejecutamos la aplicacion saldria un resultado :

Interfaces 
con 
Spring, 
solo 
en 
Java-Limos
 

pero si en el applicationContext cambiamos


< bean class="ejemplos.spring.basico.interfaces.EnviaTextos" id="enviaTextos" >
          <property name="miImpresora" ref="porLetras"/>
< / bean >

sin necesidad de recompilar, el resultado seria

I
n
t
e
r
f
a
c
e

...


esta es una ventaja mas de Spring, que sin necesidad de recompilar una aplicacion, podemos cambiar la implementacion de una interfaz simplemente modificando el applicationContext...

Primeros Pasos Con Spring I

Cuantas veces nos ha pasado que estamos realizando bien guerreros algun programita, lo ejecutamos y hoooo sale un tremendo "NullPointerException" revisamos y es que no inicializamos una variable.

Cuantas veces estamos trabajando con interfaces y se nos ocurre utilizar una implementacion distinta, pues no hay mas remedio que recompilar nuestra aplicacion...

Esto es muy molesto, mas cuando lo que se requiere es velocidad a programar (no cuenta que sea molesto por que apenas estamos aprendiendo, si ese es el caso, este post no es para ti o te haras simplemente mañoso ...)

Una de las bendiciones más basicas que nos proporciona Spring, es que nos olvidamos de las instancias, ya que todo o casi todo lo inyectamos,  no tenemos que recompilar una aplicacion para utilizar una nueva implementacion de una interfaz en nuestro sistema.

Bueno empesemos :)

Si utilidamos un IDE como NetBeans, MyEclipce, Eclipce ... basta con crear un proyecto con caracteristicas de Spring. a lo cual nos creara un archivito casi siempre en la carpeta src casi siempre se llama applicationContext.xml que tiene las siguientes caracteristicas:

1.- La version y codificacion del archivo: casi siempre 

< ?xml version="1.0" encoding="UTF-8"? > casi siempre lo que cambia es la codificacion.


2.- Los esquemas para utilizar los beans de spring que van dentro de un bloque beans


< beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" >

< /beans >

Dentro de ese bloque mapearemos nuestras clases para que se inyecten al momento de ser utilizadas, esto reemplazaara a las instancias de clases que normalmente realizamos

Supongamos que tenemos dos clases, la primera imprime en pantalla un hola mundo mas un texto y la segunda llama a la primera agregandole el texto deceado

public class Impresora{
          public void imprimirTexto(String texto){
                    System.out.println("hola mundo desde: " + texto);
          }
}

public class Textos{
          public Impresora miImpresora;

          public void setMiImpresora(Impresora miImpresora){
                     this.miImpresora = miImpresora;

          }  
          public Impresora getMiImpresora(){
                     return miImpresora;

          }
          public void mandaAImprimir(){
                     getMiImpresora().imprimirTexto("Java-Limos.blogger");
          }


NOTA: Para utilizar a miImpresora, cuando lo haciamos de la manera tradicional, muchos acostumbrabamos no encapsular la clase, para el caso de la inyeccion con spring tenemos que utilizarlo, aparte es una buena practica :)

Asumamos que tenemos nuestras dos clases en un paquete llamado "ejemplo.spring.basico", entonces procedamos a mapear nuestras clases en nuestro archivo applicationContext.xml

Dentro de nuesto bloque beans mapearemos nuestras dos clases


< bean
          class="ejemplo.spring.basico.Impresora" id="laImpresora"
/ >


Si observas dentro del bloque bean, mapeamos nuestra clase y le agregamos un identificador, esto es para ayudarnos a encontrarlo, es como si volviedamos a declarar una variable, pero esta ves en el xml


A continuacion mapearemos el segundo bean


< bean class="ejemplo.spring.basico.Textos" id="losTextos" >
          <property name="miImpresora" ref="laImpresora"/>
< / bean >

Si observas este nuevo bean, tiene una propiedad llamada "miImpresora" que no es mas que la variable miImpresora que contiene la clase Textos, y tambien tiene una referencia a "laImpresora" que es como identificamos en nuestro xml a la clase Impresora.


Ahora para que se vea aun mas, hay que crear una tercera clase con la cual inicializaremos nuestro applicationContext.xml


public class Test{
          public static void main( String args [ ] ){

                    BeanFactory fabricaDeBeans = new XmlBeanFactory ( new ClassPathResource( "/applicationContext.xml" ) );


                    Textos misTextos = (Textos)fabricaDeBeans.getBean(Textos.class); 

                    misTextos.mandaAImprimir();
          }        
}

Ahora si ejecutan su aplicacion en pantalla veran reflejado: hola mundo desde Java-Limos.blogger

QUE DIFERENCIA HAY ?

En la clase Textos nunca hicimos una instancia hacia Impresora, solo nos dedicamos a llamarla y en el caso de Impresora a darle funcionalidad

QUIEN HISO LA INSTANCIA?

La instancia se hiso desde el applicationContext, y fue responsabilidad de Spring realizar la tarea. 

QUE GANAMOS AL REALIZAR ESTO?

Tal ves escribimos mas, pero la ventaja es que spring se encarga de cargar todos los objetos mapeados antes de realizar cualquier otra cosa, por lo tanto las instancias no se realizan en tiempo de ejecucion.

Los objetos mapeados los podemos manipular para que un solo bean pueda comportarse como instancias diferentes ( en el caso de que se utilize ese bean en diferentes clases)  o podemos modificar su ambiente para que se comporte como un solo bean para todas las instancias que utilizemos.

Da mas velocidad a nuestras aplicaciones al ser Spring el que se encargue de la gestion de nuestros objetos

En el siguiente post veremos la parte de las interfaces. que es mas interesate