Category: Sin categoría


Antes de nada, Feliz año a mis escasos lectores. Últimamente ando enfangado de nuevo con Java y por supuesto, con JasperReport para sacar informes. Con la aplicación que estoy desarrollando actualmente, estoy utilizando Icefaces 3 para JSF, que da muchas facilidades para crear aplicaciones rápidamente y atractivas, tanto visual como funcionalmente. Una de las cualidades de esta versión del framework, esque todo va por AJAX. Esto, al llegar al momento de presentar al usuario los informes creados con JasperReport, supone un problema. Ya que normalmente, nos inmiscuimos en el ciclo de vida de JSF para capturar la respuesta e imprimir nuestro informe, y esto no le sienta muy bien al framework.  Así que tras unas cuantas peleas y cabezazos contra el teclado, he conseguido llegar a una solución. Dicha solución consiste en sacar el informe en otra ventana, fuera del flujo de Icefaces. Y para presentar el informe, utilizo directamente un Servlet para generar la respuesta. Paso a explicar paso a paso.

Lo primero, tenemos en nuestro archivo .xhtml lo siguiente:

<h:commandButton id="pushButtonId12"  actionListener="#{informes.pdfEdificios}"  />

Utilizamos actionListener, para que no haga ningún refresco del contenido. Ahora, el código del método encargado de manejar dicho evento es el siguiente:


public String pdfEdificios(ActionEvent event) throws IOException{
try {
Connection con = edificiosDao.getConnection();
HashMap parameters = new HashMap();
String reportsDirectory = "c:/Users/Usuario/Documents/NetBeansProjects/Proyecto/build/web/";
String jasperName = "report1.jasper";
JasperPrint jasperPrint = UtilReports.generateReport(con, reportsDirectory, jasperName, parameters);
getSessionMap().put("report",jasperPrint);
JavascriptContext.addJavascriptCall(FacesContext.getCurrentInstance(), "window.open('Report', 'myWindow');");
} catch (NamingException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
} catch (JRException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(Informes.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

En este método, simplemente generamos el informe mediante UtilReports.generateReport(con, reportsDirectory, jasperName, parameters), una vez hecho, guardamosel objeto JasperPrint a la sesión, para poder recuperarlo después en el Servlet.
Hasta este punto, ya tenemos el informe creado y guardado en la sesión, ahora necesitamos abrir el Servlet automáticamente para llevar el informe al usuario. Para ello, Icefaces nos proporciona JavascriptContext, desde el cual podemos añadir código javascript enviado desde el servidor.
Así que mediante JavascriptContext.addJavascriptCall(FacesContext.getCurrentInstance(), “window.open(‘Report’, ‘myWindow’);”); enviamos el código para que se abra una ventana nueva que lleva al servlet Report. Que habremos creado previamente con el siguiente código para manejar la respuesta:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
JasperPrint report =(JasperPrint) request.getSession().getAttribute("report");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + "report" + ".pdf;");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, report);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
exporter.exportReport();
} catch (JRException ex) {
Logger.getLogger(Report.class.getName()).log(Level.SEVERE, null, ex);
}finally{
request.getSession().removeAttribute("report");
}

}

Aquí, recuperamos de la sesión el objeto JasperPrint de nuestro informes y preparamos las cabeceras de la respuesta para indicar el tipo, y utilizamos un exporter para exportar el informe en el formato deseado (normalmente pdf). Por último, es importante poner en el bloque finally, la liberación del objeto de la sesión, para no sobrecargar la memoria del servidor.
Esta es la única forma que he encontrado, de momento, para poder mostrar los informes sin entrar en conflicto con Icefaces. Si alguién tiene una solución mejor, que no dude en comentarlo.

Hace algunos días, me he estaba preguntando cómo se podía ver de forma sencilla si algúna página utiliza algún CMS conocido (Drupal, WordPress, etc). Buscando por ahí, he encontrado el plugin Wappalyzer, está tanto para Firefox y Chrome.  Indica en la barra de direcciones mediante iconos, las tecnologías que se utilizan en la página que se está visionando. Lo bueno que no solo indica si usa algún CMS, también indica el servidor web utilizado, sistema operativo que hay por debajo, si usa Jquery, etc. Bastante completito. Este plugin puede ahorrar bastante tiempo a la hora de reunir información.

Enlace: http://wappalyzer.com/

A veces es interesante eliminar los directorios vacios de una ruta. Aunque hay formas de hacer esta tarea rápidamente con un par de comandos. He decidido hacer un script, que permite realizar esta tarea de eliminación o solo contar cuantos directorios vacios tenemos. O incluso preguntarnos antes de eliminar cada directorio, por si queremos dejar alguno sin eliminar (un directorio de plantillas por ejemplo).

El script es muy mejorable, y por ahora solo funciona en el directorio actual. Pero como ejercicio de refresco de bash scripting, me ha servido de algo.

A continuación, el código


#!/bin/bash
# Autor: Borja Rubio
# Descripcion: Script para búsqueda y eliminación de directorios vacios en el directorio actual.

function uso {
 echo "Busca los directorios vacios del directorio actual y se eliminan si así se indica."
 echo "Uso: $0 [OPCION]"
 echo -e "\t-c Muestra un conteo de directiors vacios/eliminados"
 echo -e "\t-r Elimina los directorios vacios"
 echo -e "\t-i Modo interactivo (Debe usarse junto a -r"
 echo -e "\t-h incluye los directorios ocultos"
 echo "Ejemplos:"
 echo "$0 -c -- Solo muestra el conteo de directorios vacios"
 echo "$0 -chr -- Elimina los directorios vacios, incluyendo los ocultos y muestra un resumen"
 echo "$0 -cri -- Pregunta antes de eliminar un directorio vacio"
}
if [ $# -eq 0 ] ; then
uso
exit
fi
while getopts 'hcir' OPCION
do
 case $OPCION in
 h) OCULTOS=-A
 ;;
 c) CONTEO=true
 ;;
 r) BORRAR=true
 ;;
 i) INTERACTIVE=true
 esac
done

directories=`ls $OCULTOS`
contador=0;
eliminados=0;
for j in $directories
do
 if [ -d $j ] ; then
 lines=`ls $OCULTOS $j | wc -w`
 if [ $lines -eq 0 ] ; then
 if [ $CONTEO ] ; then
 let contador=$contador+1
 fi
 if [ $BORRAR ] && [ $INTERACTIVE ] ; then
 echo "Eliminar $j ? (y/N) "
 read value
 if [ $value == "y" ] ; then
 `rmdir $j`
 let eliminados=$eliminados+1
 fi
 elif [ $BORRAR ] ; then
 `rmdir $j`
 let eliminados=$eliminados+1
 fi
 fi
 fi
done
if [ $CONTEO ] ; then
echo "$contador directorios vacios ; $eliminados directorios eliminados"
fi

Hace cosa de dos meses, me comenzó a fallar un disco duro, con la mala suerte, de ser el que tiene instalado el sistema. Los errores eran los típicos: altos tiempos de carga, reinicios extraños, algún que otro fichero corrupto. Así que me puse manos a la obra y le pasé varios escaneres de superficie, que me decian que estaba todo correcto. ¿Extraño no? El caso, que utilizando una live de recuperación, llamada Parted Magic tiene en su escritorio, uno de los programas que viene, es para examinar los discos duros. Y aquí es donde entra la tecnología SMART, que muchos hemos visto, pero al no dedicarme especialmente a esto del hardware, nunca le he prestado mucha atención en que consiste.

La wikipedia nos  dice:  “La tecnología S.M.A.R.T. acrónimo de Self Monitoring Analysis and Reporting Technology consiste en la capacidad de detección de fallos del disco duro. La detección con anticipación de los fallos en la superficie permite al usuario el poder realizar una copia de su contenido, o reemplazar el disco, antes de que se produzca una pérdida de datos irrecuperable.” Interesante ¿no? Con todos los parametros de diagnostico que nos da esta tecnología, nos podemos hacer una idea de que puede fallar en nuestro disco duro. Entre estos parametros, se encuentran algunos como la temperatura, flujo de aire, tiempo de vida del disco duro, etc. En la captura que os dejo, pertenece a un pantallazo de mi disco duro.

Parametros de SMART

Parametros de SMART

Podeis ver todos los parametros, y como nos indica uno en rojo. El parametro “End to End Error” indica que está fallando la caché del disco duro. Es un fallo muy crítico por lo que hay que salvar los datos y cambiar el disco duro cuanto antes. Como vemos, gracias a SMART, nos evitamos la sorpresa  de que el disco duro deje de fallar de un día para otro y perdamos todos esos valiosos datos.

De momento, mi disco duro aguanta, pero ya tengo pedido uno de marca Hitachi, que según me han recomendado, son mucho más fiables. También se puede ver que no llega a las 10k horas de vida. Así que es raro que tenga un fallo de este tipo, por suerte, Seagate parece que permite devolver los discos duros en garantia. Ya comentaré como funciona el proceso cuando lo intente.

Supongo que es normal que pase. Una semana sin ir a trabajar y cuando llega el domingo justo antes de entrar, ¿me voy a dormir temprano? Pues no, me busco cualquier excusa para acabar acostandome tarde. En este caso, jugueteando con unas herramientas de escaneo de puertos, sniffers y esas cosas, descubro que mi pc principal, no para de hacer peticiones ARP, preguntando por 192.168.1.69. ¿Qué es lo primero que pasa por mi cabeza? :O:O Seguro que tengo algún bicho malvado!, Pero nadie responde a la petición ARP, no responde a ping  y no me detecta ningún puerto abierto al escanear con nmap. Hasta ahí bien, pero cuando hago un scaneo de puertos desde una máquina virtual, me detecta puertos abiertos. ¿Que cosa más rara no? ¿Será cosa del VMWare y la configuración NAT? Porque en modo bridge no detecta ningún puerto abierto. Total, formas de perder el tiempo. Al final una búsqueda en el registro, encuentro que es por una impresora en red que tengo instalada, pero el pc a través de la que accede no está en la casa. ¡Normal que nadie responda! Eliminada la impresora, solucionado el problema. El modo Pingüino paranoico me ha hecho perder un montón de tiempo, porque al final, como siempre, la solución más simple es la acertada.
Pero bueno, para la próxima lo tendré en cuenta, hora de irse a dormir.

Después del parón de los exámenes volvemos a la carga. En este caso, voy a publicar la práctica de una asignatura de la carrera. El enunciado de la práctica consiste en resolver el problema del Trimino, que se trata de un tablero de X*X tamaño, siendo X una potencia de 2, y teniendo una casilla marcada. Entonces debemos recubrir el tablero utilizando triminos (un angulo de tres casillas). Una descripción más detallada del problema con su solución teórica la podemos encontrar en el siguiente enlace : http://www.dma.fi.upm.es/docencia/primerciclo/matrecreativa/juegos/poliominos/triminos/triminos.htm

Para la solución del problema se puede utilizar uno de los esquemas algorítmicos básicos, en este caso el esquema de Divide y Venceras. Que comentado por encima, consiste en coger un problema y dividirlo en partes iguales y más sencillas, hasta llegar a una solución trivial. Una vez llegada a esta solución, se va juntando las soluciones parciales para llegar a una solución completa.
La adaptación de mi esquema para este problema es el siguiente:


public static void divide(Rectangulo r){
boolean b=buscarLleno(r);
if(b) // comprobacion de si es el caso trivial
return;
// Division en subproblemas
ArrayList<Rectangulo> rects = r.dividirEnCuatro();
for(Rectangulo r1  : rects){
divide(r1); // Llamada recursiva para resolver el subproblema
}
 }

Gracias a la mayoría de las funciones auxiliares, el algoritmo  resultante es muy reducido. Pinchando aquí os podeis descargar la práctica resuelta. Podesi descargarlo de github: https://github.com/smaug1985/Trimino

Feliz año nuevo

Feliz año nuevo

He estado el fin de semana desconectado, pero Feliz año nuevo! Y que os traigan muchas cosas los reyes.

Un compañero se ha creado su propia cuenta de desarrollador de iOS en un tiempo record, menos de 48 horas. Los pasos para crear la cuenta básica, que solo permite subir aplicaciones gratuitas, los creó en poco tiempo, excepto por un par de problemillas, que resumiremos en “No inventes datos”. Mejor poner todo tal y como es, y no poner cosas como Pepe si te llamas José, etc etc. Y para la creación del contrato para poder vender aplicaciones, tampoco ha tenido muchos problemas, de ayer a hoy. Por lo visto, nisiquiera con el hecho de vender en USA, ya que según habiamos leido, había que rellenar un terrible formulario con un número de identificación fiscal estadounidense, con la consecuente llamada (y con nuestro ingles de españa profunda iba a estar jodido) . Pues no ha hecho falta, en cuanto lleguen las priemras ventas, a ver si es verdad que no le retienen impuestos los yankis. Ahora solo falta solucionar el problema del mercado japones, pero eso quedará para otro día.

Bueno, ya estamos de vuelta, después de la dura etapa de exámenes y un mes de relax. En estos meses he entrado a explorar las tecnologías móviles por motivos de trabajo. Tras un mes haciendo unas cuantas cosillas con Android, he pasado a la plataforma Iphone, y la verdad, que empezar a trabajar con los macs. Ha sido una experiencia curiosa, y supongo que los futuros posts de este blog, incluiré aparte de tecnología java, cosillas hechas para Iphone.
Como aporte, me he encontrado con el siguiente blog http://www.raywenderlich.com/ que vienen unos cuantos tutoriales bastantes apañados para empezar a hacer juegos en Iphone.

Y aun sigo de exámenes, ya he hecho dos y solo me quedan otros dos en una semana y media. Así que no tengo más remedio que ponerme las pilas y estar en casi todo mi tiempo libre disponible, estudiando.
En la búsqueda de alguna guia y ejercicios para complementar mi formación, que no siempre es suficiente con el material de la UNED, me he encontrado con la página Matemáticas bachiller y la verdad que me está resultando de muchisima ayuda, ya  que hay un monton de videos explicando álgebra, de una forma bastante sencilla de comprender y con una gran cantidad  y tipos de ejercicios.
Ahora a seguir estudiando y que la suerte esté de mi favor!