Posts Tagged ‘JAVA

11
Sep
13

Delegation (Patrón de diseño)

Para cerrar la parte de patrones fundamentales, trataremos el patrón de delegación, este patrón ha sido descrito como una manera de realizar “herencia múltiple manualmente mediante composición de objetos”.

Delegation, se trata de una técnica en la que un objeto permite mostrar cierto método al exterior, pero internamente la implementación o las acciones desencadenadas por el llamado de este método se delega a otro objeto de una clase distinta pero asociado. La delegación es utilizada como un mecanismo para centralizar en torno a un solo objeto  los compartimentos(métodos) de varios objetos donde dichos comportamientos mantienen cierto nivel de relación.

 

 

Podemos implementar Delegation de dos maneras, (1) la primera es haciendo uso de objetos dentro de otro (composición) y (2) la otra manera es la utilización de interfaces; permitiendo que la implementación del patrón pueda ser realizada, sin embargo en ocasiones la relación deseada entre clases es de contención en vez de herencia. Delegation no se limita solo a escenarios donde se debe evitar la herencia múltiple (la herencia múltiple no es permitida en Java) , pero se puede ver como una alternativa general a la herencia.

Este patrón se usa comúnmente en casos donde:

  • Se desea reducir el acoplamiento de métodos para una clase.
  • Existen componentes que tienen comportamientos similares, pero que en un futuro es posible que se realicen cambios.
  • Se desea remplazar la herencia, generalmente se usa la delegación como alternativa a la herencia.

Hay que tener en cuenta que la herencia a pesar de ser una buena estrategia para ser utilizada cuando existe una estrecha relación entre las clases involucradas, no es recomendada cuando la relación no es tan estrecha, ya que se crea una lazo de dependencia directa entre las clases; por otra parte la delegación es la forma más flexible para expresar una relación entre clases.

 

Ejemplo con clases:

package ingenio.ds.examples.patrones;
public class Clases{
	public static void main(String args[]){
		System.out.println("Usando el SuperAutoMovil");
		SuperAutoMovil superAutoMovil= new SuperAutoMovil();
		System.out.println("-- Funciones de AutoMovil:");
		superAutoMovil.iniciarMotor();
		superAutoMovil.andar();
		
		System.out.println();
		System.out.println("-- Funciones de Subergible:");
		superAutoMovil.navegar();
		superAutoMovil.navegarMasProfundo();
		superAutoMovil.navegarMasSuperficial();
		
		System.out.println();
		System.out.println("-- Funciones de Helicoptero:");
		superAutoMovil.volar();
		superAutoMovil.volarMasAlto();
		superAutoMovil.volarMasBajo();
	}
}

class Barco{
	public void iniciarMotor(){
		System.out.println("Barco: iniciando motor");
	}
	public void andar(){
		System.out.println("Barco: andando");
	}
}

class Automovil{
	public void iniciarMotor(){
		System.out.println("Automovil: iniciando motor");
	}
	public void andar(){
		System.out.println("Automovil: andando");
	}
}

class Helicoptero {
	public void iniciarMotor(){
		System.out.println("Helicoptero: iniciando motor");
	}
	public void andar(){
		System.out.println("Helicoptero: andando");
	}
	public void descender(){
		System.out.println("Helicoptero: descendiendo");
	}	
	public void ascender(){
		System.out.println("Helicoptero: ascendinedo");
	}
}

class Subergible extends Barco{
	public void descender(){
		System.out.println("Subergible: descendiendo");
	}	
	public void ascender(){
		System.out.println("Subergible: ascendinedo");
	}
}


class SuperAutoMovil extends Automovil{
	private Subergible  sumergible;
	private Helicoptero helicoptero;
	
	public SuperAutoMovil(){
		sumergible =new Subergible ();
		helicoptero=new Helicoptero();
	}
	
	public void andar(){
		super.iniciarMotor();
		super.andar();
	}
	
	public void navegar(){
		sumergible.iniciarMotor();
		sumergible.andar();
	}
	
	public void volar(){
		helicoptero.iniciarMotor();
		helicoptero.andar();
	}
	
	public void volarMasAlto(){
		helicoptero.ascender();
	}
	
	public void volarMasBajo(){
		helicoptero.descender();
	}
	
	public void navegarMasSuperficial(){
		sumergible.ascender();
	}
	
	public void navegarMasProfundo(){
		sumergible.descender();
	}
}

 
Ejemplo con interfaces:

package ingenio.ds.examples.patrones;

public class Interfaces {
	public static void main(String args[]) {
		Automovil automovil = new Automovil();
		automovil.andar();
		automovil.setMotor(new MotorElectrico());
		automovil.andar();
	}
}

interface Motor{
	public void andar();
}

class MotorVapor implements Motor {
	public void andar() {
		System.out.println("Aumenta persión");
		System.out.println("Aumenta velocidad");
	}
}

class MotorElectrico implements Motor {
	public void andar() {
		System.out.println("Aumenta revoluviones");
		System.out.println("Aumenta velocidad");
	}
}

class  Automovil{
	private Motor motor = new MotorVapor();
	
	public void andar() {
		motor.andar();
	}
	
	public void setMotor(Motor motorNuevo) {
		motor = motorNuevo;
	}
}

 

Anuncios
06
Sep
13

Programar en simple (tutoriales java EE)

Excelente fuente de recurso Java EE…

Chapter 1: Introduction

Chapter 2: Just Enough Of: Database Design

Chapter 3: JPA 2.0( Java Persistence API 2.0)

Chapter 4: EJB 3.1( Enterprise Java Beans 3.1)

Chapter 5: JSF 2.0( Java Server Faces 2.0)

Chapter 6: JMS ( Java Message Service)

Chapter 7: JAX-RS( Java API For RESTful Web Services)

Chapter 8: CDI( Contexts And Dependency Injection)

 

 

06
Sep
13

Container (Patrón de diseño)

Container o patrón de contenedores, Un contenedor es un objeto creado para contener otros objetos  y permite agregar, acceder, modificar, eliminar, en otras palabras, un contenedor debe almacenar otros objetos y permitir su gestión a través de los métodos proporcionados por la clase contenedora [en java ya existe la API Collections que describe una serie de contenedores] – colas, pilas, listas, vectores. Estos objetos (los elementos contenidos) por lo general son de tipo Object, y por herencia pueden ser de cualquier tipo  incluso pueden ser de la misma clase del contenedor. Cada Container debe implementar algún tipo de iterador asociado para permitir recorrer los elementos contenidos.

El término contenedor en la programación informática moderna realidad puede referirse a muchas cosas:

  • Los programadores de Java, C# suelen llamar a este tipo de clases de “colecciones” en lugar de “contenedores”. la Java Collections Framework proporciona implementaciones para muchos tipos de clases Container, una implementación típica de una clase de colección en Java sería ArrayList o HashMap.
  • Dentro del Framework  Spring los contenedores representan conceptos de más alto nivel, tales como la inversión de control (IoC). una explicación (en inglés) de lo que es IoC e inyección de dependencias  Inversion of Control Containers and the Dependency Injection pattern [Martin Flower].
  • Beans Enterprise son componentes de software que se ejecutan en un entorno especial llamado un contenedor EJB. Los contenedores sirven de hots y gestionan un “enterprise bean” de la misma manera que el Java Web Server aloja un servlet o un navegador HTML alberga un applet de Java.

Los usos más comunes del patrón Container son:

  • Quiere representar un grupo de objetos como uno solo.
  • Desea reutilizar funcionalidades para almacenar diferentes tipos de objetos.

Todo el código está encapsulado en unsolo archivo java

package ingenio.ds.examples.patrones;

/*definición de la interfaz mensajero*/
package ingenio.ds.examples.patrones;
import java.util.Iterator;

public class Main {

    public static void main(String[] args) {
        // Contenedor de Integer
        Contenedor contenedorEntero = new Contenedor();
        contenedorEntero.agregar(1);
        contenedorEntero.agregar(2);
        contenedorEntero.agregar(3);

        //Contenedor de String, solo soporta objetos String
        //contenedorCadena.add(1); genera error de compilacion
        Contenedor contenedorCadena = new Contenedor();
        contenedorCadena.agregar("uno");
        contenedorCadena.agregar("dos");
        contenedorCadena.agregar("tres");

        //Contenedor de Object, soporta objetos de cualquier clase
        Contenedor conetendorObject =new Contenedor();
        conetendorObject.agregar(new Integer(0));
        conetendorObject.agregar(new Double(0));
        conetendorObject.agregar(false);
        conetendorObject.agregar("String value");
        conetendorObject.agregar(0F);

       imprimir(contenedorEntero);
       imprimir(contenedorCadena);
       imprimir(conetendorObject);
    }

    public static void imprimir(Contenedor contenedor){
    	//Obtenemos el iterador
    	Iterator iterador = contenedor.iterador();
    	System.out.println("Container: ");
        while (iterador.hasNext()) {
        	Object elemento=iterador.next();
            System.out.println(elemento.getClass() +" - " + elemento);
        }
    }
}

class Contenedor {

	protected Nodo nodoInicial = null;
    protected Nodo nodoFinal = null;

    private class Nodo {
        private E elemento;
        Nodo siguiente = null;
        Nodo anterior = null;

        public Nodo(E elemento) {
            this.elemento = elemento;
        }
    }

    private class Iterador implements Iterator {
        protected Nodo nodoActual = nodoInicial;

		//retorna si tiene mas elemento
        public boolean hasNext() {
            return nodoActual != null;
        }

        //retorna el siguiente elemento
        public E next() {
            if (nodoActual == null) {
                return null;
            }
            E elemento = nodoActual.elemento;
            nodoActual = nodoActual.siguiente;
            return elemento;
        }

        //elimina el ultimo elelento retornado
        public void remove() {
            nodoActual.anterior.siguiente = nodoActual.siguiente;
            nodoActual.siguiente.anterior = nodoActual.anterior;
        }
    }

    public void agregar(E o) {
        if (nodoInicial == null) {
            nodoFinal = nodoInicial = new Nodo(o);
        } else {
            Nodo newnode = new Nodo(o);
            newnode.anterior = nodoFinal;
            nodoFinal = nodoFinal.siguiente = newnode;
        }
    }

    public Iterator iterador() {
        return new Iterador();
    }
}
21
May
13

Jasper Report (virtualización y generación de reportes)

Una de las partes a veces menos preciada, dentro de un software son los reportes que de este podemos extraer. Los reportes son documento (que puede ser impreso, digital, audiovisual, etc.) que pretende transmitir información clara y entendible acerca del estado, las características y/o circunstancias de un suceso o asunto.

 

La manera más fácil de observar el estado actual de un negocio a través de su software son las dashboard o los reportes que podemos extraer de ellos. personalmente considero que la mejor suite de reportes que conozco es la Crystal Reports, pero con la que más experiencia tengo (y de la que voy a hablar en está publicación) es Jasper Reports.

 

Jasper es una poderosa herramienta open source totalmente escrita en java y se utiliza para la creación de informes, utiliza diversas clases de data sources, también permite incluir reportes dentro de otros, y exportarlos en los formatos más comunes como son XLS, PDF, RTF, CSV, XML, TXT  y HTML.

 

Existen dos herramienta totalmente visual que nos facilita la creación de nuestros reportes Jaspersoft Studio (basado en eclipse, y cual yo utilizo) y el iReport Designer (basado en netbeans).  No entraremos en como crear reportes y que puedo hacer o no con Jasper, primero pasaremos por hacer un reporte un listado normal y como exportarlo en un formato de los anteriores mencionados; Utilizando el mismo ejemplo departamento-empleado (utilizado ya en más de una ocasión).

 

Desde está dirección podemos descargar Jasper http://sourceforge.net/projects/jasperreports/?source=dlp, jasper utiliza muchas bibliotecas las cuales también debemos incluir en nuestro classpath.

El resto de la configuración es tomada del ejemplo base (MVC en JSP), nos centraremos especialmente en lo que tiene que ver con Jasper y la generación de reportes:

En este ejemplo generaremos un solo reporte reporte_empleados.  este reporte por formato incluye dos subreportes, uno que contiene la cabecera y otro que contiene el pie de página.

reportes

reportes

Nota: Por cada reporte se muestran dos archivos uno es el archivo con el código editable y el otro es el archivo resultande de la compilación.

cabecera

cabecera (header.jrxml)

 

pie de página

pie de página (footer.jrxml)

 

reporte empleados

reporte empleados (reporte_empleados.jrxml)

 

Nota: los iconos  2013-05-21_11h15_34 indican que se está haciendo referencia a un sub-reporte  en este caso cabecera y pie de página respectivamente.

los archivos de reporte de jasper se crean en un formato .jrxml que luego de compilarlo pasa a ser .jasper se puede usar cualquiera de los dos para la generación del reportes, personalmente prefiero los .jasper porque ya están compilados y es un poco más rápido.

También hay que tener en cuenta que como estamos trabajando con Java, a los reportes debemos especificarle que estamos trabajando con ese lenguaje. Y para los reportes cuando los exportamos en HTML a las imágenes (en este caso el logo) le seteamos que sean Lazy.

Lenguaje java

Lenguaje java

Lazy

Lazy

A nivel de GUI  se creo una para generar el reporte de empleados, cuando damos clic en el botón “Generar” de Listado de empleados.

generar reportes

generar reportes

Nota: el único botón que funciona es el de listado de empleados

generar_reporte.jsp

<form action="<%=application.getAttribute("CONTROLLER").toString()%>/Generar/Reporte" method="post" enctype="application/x-www-form-urlencoded">
    <table width="100%" border="0" cellspacing="0" cellpadding="5">
        <tr>
            <td valign="top">
			Listado de empleados
            </td>
            <td>
                <select name="tipo">
                    <option value="pdf">pdf</option>
                    <option value="rtf">rtf</option>
                    <option value="xls">xls</option>
                    <option value="html">html</option>
                    <option value="xml">xml</option>
                    <option value="csv">csv</option>
                    <option value="txt">txt</option>
                </select>
            </td>
            <td>
                <input name="reporte" type="hidden" value="empleados">
                <input type="submit" value="Generar">
            </td>
        </tr>
    </table>
</form>

<form action="<%=application.getAttribute("CONTROLLER").toString()%>/Generar/Reporte" method="post" enctype="application/x-www-form-urlencoded">
    <table width="100%" border="0" cellspacing="0" cellpadding="5">
        <tr>
            <td valign="top">
			Listado de departamentos
            </td>
            <td>
                <select name="tipo">
                    <option value="pdf">pdf</option>
                    <option value="rtf">rtf</option>
                    <option value="xls">xls</option>
                    <option value="html">html</option>
                    <option value="html">xml</option>
                    <option value="html">csv</option>
                    <option value="txt">txt</option>
                </select>
            </td>
            <td>
                <input name="reporte" type="hidden" value="departamentos">
                <input name="reporte" type="button" value="Generar">
            </td>
        </tr>
    </table>
</form>

A nivel de Actions se creo uno para escribir el reporte en la salida del response GenerarReporte; esta clase se encarga de escribir por la salida el reporte.

GenerarReporte.java

package org;

//clases para que sea servlet
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import javax.servlet.ServletException;
import java.util.HashMap;

public class GenerarReporte extends Action implements Serializable {

    public void run() throws ServletException, IOException {
        try {
            String reporte = request.getParameter("reporte");
            String tipo = request.getParameter("tipo");
            /*la direccion local a la imagen del logo*/
            ReportGenerator.DIRECCION_LOGO=application.getRealPath("/shared/images/ids_report_logo.png");
            /*la direccion local de la carpeta donde se encuentral los reportes*/
            ReportGenerator.DIRECCION_REPORTES=application.getRealPath("/shared/report/")+ File.separator;

            if (tipo.matches("pdf")) {
                response.setContentType("application/pdf");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_PDF;
            } else if (tipo.matches("rtf")) {
                response.setContentType("application/rtf");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_RTF;
            } else if (tipo.matches("xls")) {
                response.setContentType("application/vnd.ms-excel");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_XLS;
            } else if (tipo.matches("html")) {
                response.setContentType("text/html");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_HTML;
                /*si elreporte es HTML la utilizamos la url para acceder a la imagen*/
                ReportGenerator.DIRECCION_LOGO=request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath()+"/shared/images/ids_report_logo.png";
            } else if (tipo.matches("xml")) {
                response.setContentType("application/xml");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_XML;
            } else if (tipo.matches("csv")) {
                response.setContentType("text/csv");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_CSV;
            } else if (tipo.matches("txt")) {
                response.setContentType("text/plain");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_TXT;
            }
            response.setHeader("Content-disposition", "attachment");
            response.setHeader("filename", reporte + "." + tipo);
            /*mandamos a crear el reporte*/
            byte[] reporteBytes = ReportGenerator.createReport(reporte, new HashMap(), model);
            OutputStream outputStream = response.getOutputStream();
            /*escribimos el reporte*/
            outputStream.write(reporteBytes);
            outputStream.flush();
        } catch (Exception ex) {
            throw new ServletException("error en GenerarReporte ", ex);
        }
    }
}

A nivel de utilidades se utiliza la clase ReportGenerator, ReportGenerator es la clase donde generamos el reporte en un formato especifico. cada formato tiene sus particularidades aunque funcionalmente y para nuestro ejemplo solo necesitamos modificar tres de estos:

exporter = new JRHtmlExporter();
exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);

Los reportes en HTML sino se le especifica  el parámetro IS_USING_IMAGES_TO_ALIGN a falso, este utilizará unas imágenes en blanco para darle espaciamiento al reporte añadiendo una lógica que para mi parecer es innecesaria (o lo ha sido hasta el momento).

exporter = new JRTextExporter();
exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, new Integer(70).floatValue());
exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, new Integer(70).floatValue());
exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Integer(15).floatValue());
exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Integer(15).floatValue());

Los reportes de tipo texto necesitan un tamaño de página y de carácter estos valores no están por defecto y sino son seteados lanzará una excepción.

exporter = new JRXlsExporter();
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);

Por estética más que por otra cosa esta es la configuración que utilizo para generar Excel desde Jasper (aunque para los reportes en realidad utilizo JExcel o POI directamente).

package org;

import java.util.Map;
import java.io.File;
import java.io.ByteArrayOutputStream;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.fill.JRFileVirtualizer;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.export.JRTextExporter;
import net.sf.jasperreports.engine.export.JRTextExporterParameter;

public class ReportGenerator {

    public static Integer FORMATO_REPORTE = 1;
    public final static Integer FORMATO_REPORTE_PDF = 1;
    public final static Integer FORMATO_REPORTE_XLS = 2;
    public final static Integer FORMATO_REPORTE_RTF = 3;
    public final static Integer FORMATO_REPORTE_HTML = 4;
    public final static Integer FORMATO_REPORTE_XML = 5;
    public final static Integer FORMATO_REPORTE_CSV = 6;
    public final static Integer FORMATO_REPORTE_TXT = 7;
    public static String DIRECCION_LOGO = null;
    public static String DIRECCION_REPORTES = null;
    private static JRFileVirtualizer reportVirtualizer = null;

    public static byte[] createReport(String nombreReporte, Map parametros, Model model) throws Exception {
        /*la virtualizacion no es obligatoria*/
        if (reportVirtualizer == null) {
            /*y de los tres metodos para virtualizar reportes prefiero la de archivos.
             utilizamos una carpeta en disco para ello*/
            String urlReportes = System.getProperty("user.home") + File.separator + "ids" + File.separator + "temp";
            File carpeta = new File(urlReportes);
            File[] archivos = carpeta.listFiles();
            /*eliminamos el contenido de dicha carpeta*/
            if(archivos!=null){
            	 for (File file : archivos) {
	                try {
	                    file.delete();
	                } catch (Exception e) {
	                    e.printStackTrace();
	                }
	            }
            }

            /*declaramos el virtualizador*/
            reportVirtualizer = new JRFileVirtualizer(10, urlReportes);
        }

        parametros.put(JRParameter.REPORT_VIRTUALIZER, reportVirtualizer);
        parametros.put("direccion_logo", DIRECCION_LOGO);
        parametros.put("titulo", nombreReporte.toUpperCase());
        parametros.put("direccion_reportes", DIRECCION_REPORTES);
        /*cargamos el archivo jasper*/
        JasperReport report = (JasperReport) JRLoader.loadObject(DIRECCION_REPORTES + "reporte_" + nombreReporte + ".jasper");
        /*cargamos la informacion*/
        JasperPrint jasperPrint = JasperFillManager.fillReport(report, parametros, model.getConexion());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        JRExporter exporter = null;
        /*configuramos la impresion del reporte dependiendo del formato*/
        if (FORMATO_REPORTE == FORMATO_REPORTE_PDF) {
            exporter = new JRPdfExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_RTF) {
            exporter = new JRRtfExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_HTML) {
            exporter = new JRHtmlExporter();
            exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_XML) {
            exporter = new JRXmlExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_CSV) {
            exporter = new JRCsvExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_TXT) {
            exporter = new JRTextExporter();
            /*para los reportes en texto debemos expresar el tamaño de la pagina*/
            exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, new Integer(70).floatValue());
            exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, new Integer(70).floatValue());
            exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Integer(15).floatValue());
            exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Integer(15).floatValue());
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_XLS) {
            exporter = new JRXlsExporter();
            /*para los reportes en excel para una mejor visualizacion utilizo esta configuracion*/
            exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
            exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
            exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
            exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
            exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);
        }
        /*marcamos PDF como el formato predeterminado*/
        FORMATO_REPORTE = FORMATO_REPORTE_PDF;
        /*exportamos el reporte*/
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
        exporter.exportReport();
        /*obtenemos el byte[] que representa ek archivo*/
        if (baos != null) {
            /*llamamos al garbage collector*/
            System.gc();
            return baos.toByteArray();
        }
        return null;
    }
}

Otro tema que se esta incluyendo en esta clase es la Virtualización de los reportes en Jasper (la virtualización, data sources y el ciclo de vida de un reporte jasper serán tratados a futuro) tiene utilidad en caso de reportes muy grande ya que la información se carga en memoria y puede generar una OutOfMemoryException, la virtualización se utiliza para almacenar la información del reporte de manera temporal en otra disposición (afectando el rendimiento) garantizando que la memoria no se llenará a causa de Jasper y evitando un colapso en el sistema.

15
May
13

Monitorear el Servidor con Java Management eXtensions (JMX)

En ocasiones se hace necesario monitorear las actividades de nuestro servidor para conocer su estado, en mi caso la necesidad surgió cuando este al desplegar la aplicación comenzaba a bajar el rendimiento hasta colapsar. Actividad que en realidad es muy sencilla,  ya que java provee una API que nos permite realizarla; la Java Management eXtensions, La tecnología JMX proporciona una forma simple y estándar para gestionar recursos de aplicaciones, dispositivos y/o servicios. Debido a que la tecnología JMX es dinámica, se puede usar para controlar y gestionar los recursos a medida que se crean, se instalan o son  implementados. También puede utilizar la tecnología JMX para supervisar y gestionar la Máquina Virtual Java (Java VM).

Nota: En mi caso utilizo Tomcat sobre Windows 7.

Primero descargamos catalina-jmx-remote.jar, de igual manera (para mi la que mejor me pareció) descargamos visualvm que es el software que nos permitirá observar la actividad y estado del servidor.

 

Copiamos el catalina-jmx-remote.jar en la carpeta de las bibliotecas de nuestro server.

catalina-jmx-remote

catalina-jmx-remote

En el archivo de configuración del servidor llamado server.xml, ubicado en $CATALINA_BASE/conf/ (para mi caso C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\)  agregamos una linea donde describimos los puertos que utilizaremos para realizar la conexión:

 

<Listener className=”org.apache.catalina.mbeans.JmxRemoteLifecycleListener” rmiRegistryPortPlatform=”10001″ rmiServerPortPlatform=”10002″/>

listener

listener

Nota: por lo generar esta linea ya aparece incluida en el archivo server.xml como un comentario.

 

 

Modificamos los parámetros con los que inicia el servidor  para llamar a las opciones de JMX (las cuales pueden ser modificadas a necesidad pero)   para mi caso agregué las siguientes lineas a los parámetros con los que se inicia:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6060
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.password.file=C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\jmxremote.password
-Dcom.sun.management.jmxremote.access.file=C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\jmxremote.access

Nota: si -Dcom.sun.management.jmxremote.authenticate=false no es necesario describir los archivos de password y access

 

Hemos descrito dentro de los parámetros de inicio dos archivos: jmxremote.passwordjmxremote.access, archivos de texto plano que contienen las contraseñas y los tipos de acceso a JMX respectivamente:

 

 jmxremote.password   jmxremote.access
controlRole control
monitorRole monitor
  controlRole readwrite
monitorRole readonly

 

El siguiente paso a seguir es iniciar nuestro servidor. y conectarnos por JMX, en este punto iniciamos el visualvm y agregamos una nueva conexión JMX y listo ya estamos viendo el comportamiento del server.

Conectarse por JMX

Conectarse por JMX

los parámetros para la conexión serían:

Connection: service:jmx:rmi://localhost:10002/jndi/rmi://localhost:10001/jmxrmi
Username: monitorRole
Password: monitor

Server status

Server status

 

 

Nota: el archivo de password debe ser configurado para que sea de solo lectura y solo puede ser visto por el usuario que lo creo que a su vez debe ser el mismo usuario con el que inicia el servidor.

Referencias

09
May
13

Interface (Patrón de diseño)

Una interfaz se define como una “Conexión física y funcional entre dos aparatos o sistemas independientes” [Rae 2013], esta describe las operaciones (la cara al mundo) que una entidad puede realizar, de igual manera establece los limites, niveles de acceso y la manera en que se desarrolla la comunicación entre dos entidades, para nuestro caso caso dos piezas de software. Por lo general, se refiere a una abstracción que proporciona un activo de sí mismo a la parte exterior.

 

La idea principal de una interfaz es separar las funciones (firma de métodos) de las implementaciones (cuerpo del método) . Cualquier solicitud que coincida con la firma de la interfaz de un objeto también puede ser enviada a ese objeto, independientemente de su aplicación. Restando importancia a cual clase realiza la implementación y responda el llamado ya que el llamado se hace sobre la interfaz, brindando la capacidad de poder intercambiar fácilmente la clase que implementa la interfaz sin modificar el código donde se hace el llamado a dicha interfaz.

 

 

El concepto de una interfaz es fundamental en la mayoría de los lenguajes de programación orientados a objetos. En algunos, los objetos son conocidos sólo a través de sus interfaces de modo que no hay manera de acceder a un objeto sin tener que ir a través de su interfaz.

 

Los usos más comunes para las interfaces son:

  • Deseamos describir la el protocolo de comunicación de una clase fuera de su paquete.
  • Se debe cambiar la implementación de una funcionalidad en tiempo de ejecución.
  • Durante el diseño desconocemos cual será la implementación que se usará en tiempo de compilación.

 
Interfaces.java

package ingenio.ds.examples.patrones;

/*definición de la interfaz mensajero*/
interface Mensajero{
	/*definición del método enviar*/
	public void enviar(String titulo,String mensaje);
}

Clases.java

package ingenio.ds.examples.patrones;
import javax.swing.JOptionPane;

class Consola implements Mensajero{
	public void enviar(String titulo,String mensaje){
		System.out.println("Log : "+mensaje);
	}
}

class Popup implements Mensajero{
	public void enviar(String titulo,String mensaje){
		JOptionPane.showMessageDialog(null,
									 mensaje,
									 titulo,
									 JOptionPane.INFORMATION_MESSAGE);
	}
}

Main.java

package ingenio.ds.examples.patrones;

public class Main {
	/*describe el tipo de mensaje que usaremos*/
	public static String TIPO_MENSAJE="CONSOLA";
	public static void main(String argumentos[]){
		/*en este punto no conocemos la implementación que se usará para enviar el mensaje*/
		Mensajero mensajero=getMensajero();
		/*llamamos el método enviar */
		mensajero.enviar("Hola","Iniciar envio de mensaje");
		mensajero=getMensajero();
		mensajero.enviar("Hola","Patrón interface");
		mensajero=getMensajero();
		mensajero.enviar("Hola","Cerrar envio de mensaje");
	}

	public static Mensajero getMensajero(){
		/*dependiendo del 'contexto' retornará el mensajero necesario*/
		Mensajero mensajero=null;
		if(TIPO_MENSAJE=="CONSOLA"){
			mensajero=new Consola();
			TIPO_MENSAJE="POPUP";
		}else{
			mensajero=new Popup();
			TIPO_MENSAJE="CONSOLA";
		}
		return mensajero;
	}
}
30
Abr
13

Redimensionamiento de imagenes en Java

Hace poco un compañero requería una funcionalidad que le entregase las fotos que tiene en el servidor en un tamaño “estándar” para que al momento de mostrarlas no hubiese unas muy grandes y otras pequeñas y así todas tendrían aproximadamente el mismo tamaño. entonces entre varias páginas pude construir una pequeña clase que:

  • Carga una imagen
  • Redimensiona una imagen
  • Guarda una imagen
  • Realiza una copia redimensionada de la imagen
package ingenio.ds.util.image;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImageResizer {
	//Ancho máximo
    public static int MAX_WIDTH=800;
	//Alto máximo
    public static int MAX_HEIGHT=800;

	/*Este método es el de la magia recibe la ruta al archivo original y la ruta donde vamos a guardar la copia
	copyImage("C:\\Users\\IngenioDS\\Desktop\\test.png","C:\\Users\\IngenioDS\\Desktop\\Copia\\test2.png");*/

    public static void copyImage(String filePath, String copyPath) {
        BufferedImage bimage = loadImage(filePath);
        if(bimage.getHeight()>bimage.getWidth()){
        	int heigt = (bimage.getHeight() * MAX_WIDTH) / bimage.getWidth();
            bimage = resize(bimage, MAX_WIDTH, heigt);
        	int width = (bimage.getWidth() * MAX_HEIGHT) / bimage.getHeight();
            bimage = resize(bimage, width, MAX_HEIGHT);
        }else{
        	int width = (bimage.getWidth() * MAX_HEIGHT) / bimage.getHeight();
            bimage = resize(bimage, width, MAX_HEIGHT);
        	int heigt = (bimage.getHeight() * MAX_WIDTH) / bimage.getWidth();
            bimage = resize(bimage, MAX_WIDTH, heigt);
        }
        saveImage(bimage, copyPath);
    }
	
	/*
	Este método se utiliza para cargar la imagen de disco
	*/
    public static BufferedImage loadImage(String pathName) {
        BufferedImage bimage = null;
        try {
            bimage = ImageIO.read(new File(pathName));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bimage;
    }

    /*
	Este método se utiliza para almacenar la imagen en disco
	*/
	public static void saveImage(BufferedImage bufferedImage, String pathName) {
        try {
            String format = (pathName.endsWith(".png")) ? "png" : "jpg";
            File file =new File(pathName);
            file.getParentFile().mkdirs();
            ImageIO.write(bufferedImage, format, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
	/*
	Este método se utiliza para redimensionar la imagen
	*/
    public static BufferedImage resize(BufferedImage bufferedImage, int newW, int newH) {
        int w = bufferedImage.getWidth();
        int h = bufferedImage.getHeight();
        BufferedImage bufim = new BufferedImage(newW, newH, bufferedImage.getType());
        Graphics2D g = bufim.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(bufferedImage, 0, 0, newW, newH, 0, 0, w, h, null);
        g.dispose();
        return bufim;
    }
}



I+Ds

Dudas consultas
Facebook
Twiter
Google +

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevas publicaciones por correo.

Únete a otros 350 seguidores

Redes Sociales y Archivos

Entradas

diciembre 2017
L M X J V S D
« Abr    
 123
45678910
11121314151617
18192021222324
25262728293031

IngenioDS en twiter


A %d blogueros les gusta esto: