sábado, 31 de diciembre de 2011

Lector de comics para mobiles (java j2me)

El día de hoy voy a hablar de un pequeño proyecto que inicié.

La idea es simple: Poder ver el cómic diario de Garfield desde mi celular. Me gusta mucho leer dicha tira cómica y me resulta más simple y cómodo cargarla diariamente en mi celular ya que es una imagen pequeña por lo general.

El proyecto está en sus inicios y un poco abandonado pues he tenido mucho trabajo estos últimos meses pero pueden verlo en el repositorio público aquí (BitBucket.org).

Lo desarrollé usando NetBeans y J2ME. Para ejecutarlo necesitamos un dispositivo movil con soporte para MIDP 2.0. Yo lo probé en un Sony Ericsson Satio que tengo.

En un futuro planeo arreglar varias cosas entre ellas:

  • Soporte para varios dispositivos, posiblemente migrarlo a PhoneGap.
  • Actualizar el código fuente para que esté bajo GPL.
  • Mejorar la interfaz de usuario.
Hasta la próxima.

Convertir de SQL a Linq


Recientemente he estado trabajando mucho con .Net y aunque ya lo he dicho antes lo vuelvo a repetir ¡La gran mayoría de las cosas no me gustan! sin embargo eh estado encontrando buenas técnologias que valen la pena aprenderlas, entre ellas el muy conocido Linq.

Una de las principales razones para usar Linq es el hecho de que es independiente de la tecnología de almacenamiento de datos que está debajo, por ejemplo les dejo una lista de los Proveedores que actualmente existen para linq aquí y aquí una página donde explican en más detalle porque linq es mejor que usar SQL directamente.

Hoy escribo este post para dejar una pequeña documentación de como transformar consultas SQL a Linq usando Linqer.

Linqer me ayudó mucho con la conversión de SQL a Linq y la recomiendo en especial cuando quieren hacer el trabajo rápidamente además que es muy buena para aprender linq aunque lastimosamente no es libre: http://www.sqltolinq.com/


Para los efectos de mis ejemplos crearé una base de datos llamada sample1 con las siguientes tablas: table_1, table_2 y table_3 y a continuación el script sql, más simple que me es posible crear con lo que tengo a mano, es muy probable que si lo desean usar tengan que hacer algunos cambios para que funcione en su DBMS (MySQL, MS SQL Server, Oracle, etc)


Bueno manos a la obra:
1. Select simple
  • SQL: SELECT * FROM table_1
  • Linq: from table_1 in context.Table_1
    select new {
      table_1.Col_1,
      table_1.Col_2,
      table_1.Col_3
    }

2. Select con condicional:
  • SQL: SELECT * FROM table_2 WHERE col_1 <= 10 and col_2 = 'something'
  • Linq: from table_2 in context.Table_2
    where
      table_2.Col_1 <= 10 &&
      table_2.Col_2 == "something"
    select new {
      table_2.Col_1,
      table_2.Table_1_col_1,
      table_2.Col_2,
      table_2.Col_3
    }

3. Select con un group by simple:
  • SQL: SELECT SUM(col_3) sumatory, col_2 FROM Table_1 GROUP BY col_2
  • Linq: from table_1 in context.Table_1
    group table_1 by new { 
       table_1.Col_2
    } into g
    select new {
      sumatory = (System.Decimal?)g.Sum(p => p.Col_3),
      g.Key.Col_2
    }
En este punto es donde Linq se pone algo complicado por la sintaxis del group by


4. Join (old style):
  • SQL: SELECT t1.col_2, t1.col_3, t2.col_3, t3.col_1
    FROM Table_1 t1, Table_2 t2, Table_3 t3
    WHERE t1.col_1 = t2.table_1_col_1 and t2.col_1 = t3.table_2_col_1

    and t1.col_1 = t3.table_1_col_1
  • Linq: from t1 in context.Table_1
    from t2 in context.Table_2

    from t3 in context.Table_3
    where
         t1.Col_1 == t2.Table_1_col_1 &&
         t2.Col_1 == t3.Table_2_col_1 &&
         t1.Col_1 == t3.Table_1_col_1
    select new {
         t1.Col_2,
         t1.Col_3,
         Column1 = t2.Col_3,
         t3.Col_1
    }

5. Inner Join (ansi join), alternativa al ejemplo anterior
  • SQL: SELECT t1.col_2, t1.col_3, t2.col_3, t3.col_1
             FROM  Table_1 t1 inner join Table_2 t2 on t1.col_1 = t2.table_1_col_1
                inner join Table_3 t3 on t2.col_1 = t3.table_2_col_1 
                    and t1.col_1 = t3.table_1_col_1
  • Linq: from t1 in context.Table_1
    join t2 in context.Table_2
          on new { Col_1 = t1.Col_1 } equals new { Col_1 = t2.Table_1_col_1 }
    join t3 in context.Table_3
          on new { t2.Col_1, Column1 = t1.Col_1 } equals new { Col_1 = t3.Table_2_col_1, Column1 = t3.Table_1_col_1 }
    select new {
      t1.Col_2,
      t1.Col_3,
      Column1 = t2.Col_3,
      t3.Col_1
    }
6. Como ultimo ejemplo un join old style que además tiene un group by
  • SQL: SELECT t1.col_2, t3.col_1, SUM(t1.col_3) sumatory
    FROM Table_1 t1, Table_2 t2, Table_3 t3
    WHERE t1.col_1 = t2.table_1_col_1
    and t2.col_1 = t3.table_2_col_1
    and t1.col_1 = t3.table_1_col_1
    GROUP BY
    t1.col_2, t3.col_1
  • Linq: from t1 in context.Table_1
    from t2 in context.Table_2
    from t3 in context.Table_3
    where
      t1.Col_1 == t2.Table_1_col_1 &&
      t2.Col_1 == t3.Table_2_col_1 &&
      t1.Col_1 == t3.Table_1_col_1
    group new {t1, t3} by new { t1.Col_2, t3.Col_1 } into g
    select new {
      g.Key.Col_2,
      Col_1 = (System.Int32?)g.Key.Col_1,
      sumatory = (System.Decimal?)g.Sum(p => p.t1.Col_3)
    }

Hay muchas otras combinaciones que podría poner pero haría este post demasiado extenso, creo que con esto tenemos suficiente para hacernos una idea de como convertir de SQL a Linq.

No puedo dejar de mencionar LinqPad que es una buena herramienta para practicar Linq y mejorar nuestro conocimiento del mismo.

Hasta la próxima.

    miércoles, 7 de diciembre de 2011

    Internacionalizacion en asp.net con gettext

    Desde hace algún tiempo que estoy buscando una forma de usar gettext en mis proyectos asp.net para soportar internacionalización también abreviada como i18n ¿por qué?, hay muchas razones pero las principales para mi son:
    1. Es software libre.
    2. Hay muy buenas herramientas tanto para GNU/Linux como para otros OS.
    3. Es muy popular y muchos proyectos lo usan, lo cual hace más simple que los traductores puedan ayudar con los muchos lenguajes que yo no domino.
    4. Es mucho más simple que la forma soportada por asp.net.

    Ya tengo un proyecto asp.net creado en github, así que lo usaré para los ejemplos.

    Estoy basandome en este artículo publicado por Jason Kester.

    A continuación los pasos a seguir:

    1. Agregar gettext al proyecto. Para esto descargamos la librería FairlyLocal y colocamos los dll en algún lugar accesible para nuestra aplicación y copiamos las clases de ejemplo Internationalization, Localization y Message dentro del proyecto.

    2. Creamos una interfaz que define el helper para soportar i18n (esta interfaz y su implementación están basadas en los ejemplos de la librería FairyLocal):


    3. Ahora modificamos la interfaz IPage, de mi post anterior, para poder insertar el recurso de i18n:


    4.Mediante inyección de dependencias (DI por sus siglas en ingles) proveemos un helper que manejará la lógica de acceso gettext. La forma como implementé la DI la explico en un post anterior. Esto significa que debemos modificar la clase SimpleInjectorPageHandlerFactory.

    5. Modificamos nuestra aplicación para que use la función "_" donde haga falta.


    6. Y el ultimo paso es agregar un script de post construcción (post-build) para que gestione la creación de los archivos .po (a menos claro que prefieran hacerlo manualmente).
    Aqui cabe señalar que existen dos tipos de aplicación web en asp.net, a saber: WSP (web site project) y WAP (web application project); más aquí. Esto es importante porque solo en los WAP existe la posibilidad de crear post-build scripts, pero si tenemos una aplicación WSP lo que debemos hacer es crear un proyecto extra y agregarlo a la solución, por simplicidad recomiendo que sea una librería pero cualquier tipo de proyecto que soporte este tipo de scripts funciona.
    A continuación les dejo mi script


    Cabe señalar que este post-build script tiene que incluir todos los tipos de archivos fuente que nuestro proyecto tiene para que pueda crear correctamente todas las cadenas que requieren una traducción.

    Lo que sigue es traducir o solicitar a nuestros amigos, colegas, traductores pagados, etc que nos den una mano.

    Hasta la próxima.

    martes, 6 de diciembre de 2011

    Dependency Injection sencillo en asp.net

    Siguiendo un poco el hilo de mi post anterior Seguridad Flexible en asp.net usando módulos hago este donde veremos como implementar nuestro propia y muy simple Inyección de Dependencias (Dependency Injection, DI) que es una forma de inversión de control.

    Antes de seguir es bueno comentar que si alguna vez necesitan hacer algo como esto, pueden considerar usar SpringNet el cual no sólo ofrece DI sino muchas otras funcionalidades, aunque no lo he probado en .Net sí lo he usado mucho la versión en Java y me ha sido de gran utilidad.

    Bueno manos a la obra:
    Primero que nada vamos  necesitar definir la forma como se injectaran las dependencias y quien será el responsable:
    1. La forma, haré que todas mis páginas implementen una interfaz la cual el objeto responsable de inyectar las dependencias reconocerá, recuerden que esta es una versión simplificada de un DI
    2. El responsable de inyectar las dependencias necesarias a las páginas será una clase que implemente la interfaz IHttpHandlerFactory llamada SimpleInjectorPageHandlerFactory, en dicha clase extenderemos al PageHandlerFactory que define asp.net para que la implementación sea más simple.
    Para que la inyección funcione necesitamos configurar que los requests que soliciten páginas aspx sean procesados por nuestra clase, en la sección httpHandlers creamos una entrada nueva de la siguiente forma: 
    <add verb="*" path="*.aspx" type="lib.ioc.di.SimpleInjectorPageHandlerFactory"/>
    a continuación un ejemplo de como luce el web.config:



    Aquí solo demostraré como hacer funcionar todo el mecanismo de inyección y en un post siguiente hablaré de como usar este mecanismo para soportar internacionalización en asp.net usando gettext.

    Todo el código está en la misma aplicación de ejemplo del post anterior y la pueden encontrar aquí. Allí puse una interfaz IResource con una implementación sencilla solo para demostrar que funciona.


    Hasta la próxima.

    martes, 22 de noviembre de 2011

    Seguridad flexible en asp.net usando Modulos

    Hace poco, mientras trabajaba en un proyecto para un cliente en ASP.Net, no precisamente mi fuerte ni mucho menos mi favorito, tuve que trabajar en una implementación de seguridad.

    Mi conversación con el cliente fue más o menos como sigue:

    Cliente: "Queremos tener una forma flexible de crear roles en el sistema y asignar dichos roles a los usuarios y páginas del sitio de forma que el administrador tenga control de quien puede ver que en la aplicación"

    Yo: "Es decir que quieren cargar los usuarios y sus roles desde la base de datos (algo que ya hacemos) y además los roles de las páginas desde la base de datos ¿correcto?"

    Cliente: "Sí, es correcto"

    Después de un poco de investigación me vino a la mente implementar esto usando un IHttpModule que interceptara los request a la aplicación y allí hacer las validaciones correspondientes.

    Todo el código de este proyecto de ejemplo lo subí a GitHub aquí y está bajo licencia apache, así que adentale si desean bajarlo y usarlo y/o mejorarlo, cualquier comentario es bienvenido.
    Por cierto casi se me olvida mencionar que estoy usando BLToolkit  para la capa de acceso a datos.


    A continuación cómo resolví el problema:

    1. Diseñemos las tablas y sus relaciones y las creamos en la base de datos
    2. Implementamos la interfaz IHttpModule:

    3. Para poder probar nuestra aplicación decidí configurar un MembershipProvider para validar los usuarios y un RoleProvider para cargar los roles de usuarios. Para más detalles de la forma como implementé estos providers pueden ver el proyecto de ejemplo aquí.

    4. Y por supuesto debemos configurar los providers y el modulo antes mencionados en el Web.config

    Y todo listo para probar, solo necesitamos ejecutar el proyecto si estas usando VisualStudio o instalarlo en el servidor por ejemplo IIS.

    Más sobre como implementar providers para asp.net aquí y aquí.

    Hasta la próxima.

    viernes, 2 de septiembre de 2011

    Como usar tu rostro para iniciar sesión en ubuntu

    Aprovechando que hoy configuré pam_usb para iniciar sesión usando una usb, me decidí a documentar algo que hace rato tengo en mi laptop: el modulo pam_face_authentication por medio del cual podemos iniciar sesión usando nuestro rostro. Inspirado por un post de mi amigo ahioros (Reconocimiento Facial Arch Linux), busqué y encontré como instalar dicho modulo en ubuntu, aquí dejo el tutorial oficial en el sitio del proyecto. Los pasos que yo seguí son los siguientes:

    1. En una terminal ejecutamos los siguientes comandos:

    sudo add-apt-repository ppa:antonio.chiurazzi
    sudo apt-get update
    sudo apt-get install pam-face-authentication
    


    2. editamos el archivo /etc/pam.d/common-auth

    # nano /etc/pam.d/common-auth
    
    Y añandimos la linea "auth sufficient pam_face_authentication.so enableX" entre la línea que define el pam_usb.so y "auth [success=2 default=ignore] pam_unix.so nullok_secure" Para que nos quede como se muestra a continuación:
    ...
    
    # here are the per-package modules (the "Primary" block)
    auth    sufficient      pam_usb.so
    auth    sufficient      pam_face_authentication.so enableX
    auth    [success=2 default=ignore]      pam_unix.so nullok_secure
    
    ...
    
    Como pueden notar tengo colocado el modulo pam_usb arriba, luego pam_face_authentication y luego los que por defecto vinieron en ubuntu. De este modo primero se intenta la validación por usb, si esta es exitosa se inicia la sesión sino se intenta con el reconocimiento facial y finalmente el sistema solicita la contraseña si todo lo demás falla.

    Es todo por el momento. Hasta la proxima.

    Como usar la usb para iniciar sesion en ubuntu

    Como ya es costumbre mía estaba leyendo en internet sobre consejos de seguridad y encontré una lista de 20 consejos para mejorar la seguridad del openssh en un servidor, el consejo que más me llamó la atención fue habilitar el "two-factor authentication", que es básicamente crear una llave RSA y mover la llave privada a un usb, entonces cuando llamas al comando ssh con la opción -i para decirle cual llave privada usar. Después de pensarlo un rato me pregunté ¿podré configurar esto del two-factor authentication en mi Ubuntu de uso personal (en este caso mi laptop)? Investigué un poco y para mi sorpresa no solo es posible sino bastante fácil, así que aquí dejo los pasos y las referencias:

    Pasos a seguir:
    1. Instalamos los programas necesarios:
    sudo apt-get install pamusb-tools libpam-usb
    
    2. Conectamos una USB a la computadora
    
    3. Agregamos el USB a la configuración del PAM:
    
    $ sudo pamusb-conf --verbose --add-device=my-usb
    Inspecting /org/freedesktop/Hal/devices/storage_serial_*******************************
     Invalid: Device does not contain any volume
    Inspecting /org/freedesktop/Hal/devices/storage_serial_SanDisk_Cruzer_Blade_*************************
     Valid
    Please select the device you wish to add.
    * Using "SanDisk Cruzer Blade (*****************************************)" (only option)
    
    Which volume would you like to use for storing data ?
    * Using "/dev/sdb1 (UUID: AAAA-9999)" (only option)
    
    Name  : my-usb
    Vendor  : SanDisk
    Model  : Cruzer Blade
    Serial  : *****************************************
    UUID  : AAAA-9999
    
    Save to /etc/pamusb.conf ?
    [Y/n] y
    Done.
    
    
    4. Agregamos el usuario que podrá usar el usb (my-usb) para ingresar.
    
    $ sudo pamusb-conf --add-user myuser --verbose
    Which device would you like to use for authentication ?
    * Using "my-usb" (only option)
    
    User  : myuser
    Device  : my-usb
    
    Save to /etc/pamusb.conf ?
    [Y/n] y
    Done.
    
    
    5. Configuramos el sistema para que permita el inicio de sesión usando el modulo pam_usb:
    Tenemos que editar el archivo common-auth
    
    sudo nano /etc/pam.d/common-auth 
    
    Buscamos la línea que dice auth required pam_unix.so nullok_secure y agregamos la siguiente línea: auth sufficient pam_usb.so. Aquí dejo un ejemplo de como quedó mi archivo /etc/pam.d/common-auth
    auth    sufficient      pam_usb.so
    auth    required        pam_unix.so nullok_secure
    
    Nota: realmente importante, por favor tener mucho cuidado al editar este archivo pues si lo dejan mal terminaran con un sistema al que no podrá ingresar, el post original recomiendan dejar una consola con permisos de administrador y el archivo abierto pues en caso de que algo salga mal puedan arreglarlo.

    Probar que funciona: Al momento de redactar este tutorial no he verificado cerrar mi sesión e ingresar otra vez usando la usb, pero si ejecute la siguiente prueba indicada en el post original y me funcionó bien:
    $ su myuser
    * pam_usb v0.4.2
    * Authentication request for user "myuser" (su)
    * Device "my-usb" is connected (good).
    * Performing one time pad verification...
    * Regenerating new pads...
    * Access granted.
    


    Alternativa, Requerir tanto el usb como una contraseña: De acuerdo con el post original si deseamos que ambos, la contraseña y el usb sean requeridos para ingresar debemos modificar el archivo /ect/pam.d/common-auth para que quede de la siguiente forma:
    auth    required      pam_usb.so
    auth    required        pam_unix.so nullok_secure
    
    Y al probarlo de la misma forma antes mencionada debemos ver algo como lo siguiente:
    $ su ubuntu-user
    * pam_usb v0.4.2
    * Authentication request for user "ubuntu-user" (su)
    * Device "my-usb" is connected (good).
    * Performing one time pad verification...
    * Access granted.
    Password:
    
    Donde como pueden ver se valida la presencia del usb y luego se solicita la contraseña.

    Alternativa, Bloquear/Desbloquear el equipo cuando se remueve/reconecta la usb:  Modificamos el archivo /etc/pamusb.conf, específicamente la sección user, en dicha sección debe estar ya creada y con una entrada indicando el dispositivo que el usuario requiere para ingresar, solo debemos agrergar dos entradas más de modo que quede más o menos como el siguiente ejemplo:
     
               
                      my-usb
               
              gnome-screensaver-command -l 
              gnome-screensaver-command -d 
     
    
    Nota: si no usas gnome reemplaza el comando gnome-screensaver-command por algo que si te funcione.

    Conclusión Esta forma de ingresar me trae algunas ideas sobre como se podría en una empresa o institución eliminar la necesidad de usar contraseñas o agregar una capa más de seguridad. Se imaginan llegando a su puesto de trabajo y colocando una usb en la pc y luego empezar a trabajar sin tener que hacer más nada. Hasta la próxima. Referencias: http://askubuntu.com/questions/10524/usb-drive-login-token-system http://linuxconfig.org/linux-authentication-login-with-usb-device

    Actualización 3-sep-2011:  después de salir y volver a ingresar pude comprobar que la validación por usb funciona bien en el inicio de sesión.

    Actualización 7-ene-2012: tristemente el proyecto pamusb parece estar muerto, incluso ya eliminaron el paquete de Debían y  Ubuntu :(

    jueves, 2 de junio de 2011

    Coding dojo durante el FUDCon Panamá 2011

    Mecánica de trabajo del coding dojo(Para los que no saben como funciona):
    En un coding dojo se promueve la práctica de Test Driven Development (TDD).
    Todos los participantes usan una misma computadora y toman turnos de 7 minutos para intentar resolver el problema presentado, entre tanto que otro miembro del
    equipo se sienta a su lado haciendo las veces de couch y ayudando al que se encuentra tratando de resolver el problema; Cuando el tiempo se acaba el couch
    se convierte en quien trata de resolver el problema y el siguiente que está esperando en la cola se convierte en el couch mientras que el que estaba antes programando pasa al final de la cola.
    Todo este proceso se repite hasta resolver el problema o se termine el tiempo designado para el coding dojo.

    La principal meta del coding dojo es que los participantes se diviertan resolviendo los problemas.


    Cree un repositorio en github para guardar el código creado durante el coding dojo: https://github.com/emont01/FUDCon2011-pa-coding-dojo

    En este coding dojo se resolvieron dos problemas
    1. Tomar un arreglo de números como parámetro, extraer los números no repetidos y ordenar los mismos. Lo resolvimos en aproximadamente 40 minutos.

    2. Convertir de números romanos a entero y viceversa. Este problema quedó pendiente en el coding dojo pero pueden encontrar mi solución en el repositorio github.

    Documentation usando herramientas libres

    Una conferencia dictada por Jared Smith (Lider del proyecto Fedora).

    En esta conferencia Jared nos habló sobre como crear documentación usando DocBook, un sistema para escribir documentos estructurados usando XML, el cual es excelente para escribir libros y artículos acerca de cualquier tema. Es un formato amplio y robusto y debido a su estructura refleja muy bien la nocion de lo que constituye un libro, DocBook ha sido adoptado por una larga y creciente comunidad de autores.

    Entre sus principales características y ventajas tenemos:
    • usa XML
    • permite una separación del contenido y la presentación
    • se puede convertir fácilmente en otros formatos como LaTex, HTML, pdf entre otros.
    • un autor solo precisa escribir su libro una vez y usando la capacidad de conversión del XML con DocBook se pueden generar prácticamente de inmediato muchos libros en distintos formatos (epub, HTML, LaTex, pdf, etc)
    • existe soporte en varios editores
    • existe la posibilidad de dividir un libro en varias partes más pequeñas usando Xincludes
    • es posible hacer algunas versiones para objetivos específicos.
    • soporta la creación de entidades que pueden ser usadas para evitar repeter ciertos textos una y otra vez.

    ¿ejemplos y tags soportados?
    La documentación de DocBook es muy completa y extensa por lo que recomiendo leerla y también mirar algunos ejemplos.

    ¿Herramientas recomendadas?

    Publican es un sistema de publicación para DocBook, además de una herramienta de procesamiento. Además de validar que nuestro XML (DocBook) es válido, publica, se asegura de que cumple con los estandares de un documento "publicable"

    Publican permite crear documentos en formato DocBook así como convertirlos en muchos otros formatos de forma muy simple.

    Aunque admito que tengo que leer un poco más sobre publican, en su presentación Jared demostró que es muy simple crear documentos y convertir los a otros formatos usando esta herramienta.

    Saludos.

    miércoles, 1 de junio de 2011

    De qué vive la gente que trabaja en software libre

    Presentado por Edwind Contreras (Venezuela)

    Como parte de las presentaciones dadas el primer día del FUDCon y de las que aun no había podido escribir se encuentra la dictada por richzendy titulada: "De qué vive la gente que trabaja en software libre".

    Para empezar richzendy nos explicó las diferentes ventajas de representa el uso de software libre en distintos entornos por ejemplo:

    en las escuelas:
    • ahorra costos,
    • satisface la curiosidad,
    • tesis que realmente ayudan a la sociedad,
    • permite aprender haciendo,
    • permite evitar que en las universidades se "reinvente la rueda" haciendo que los estudiantes hagan una y otra ves los mismos programas, resolviendo una y otra vez los mismos problemas. Es mejor pedir a los estudiantes que mejoren software libre ya existente.
    en la sociedad:
    • libertad, libertad, libertad desde siempre la sociedad ya tomado los inventos creados por un hombre, los ha mejorado y les ha dado nuevos usos y para eso necesitamos saber como funcionan
    • como mencionamos antes 'reinventar la rueda es de tontos' y en una sociedad donde se puede reutilizar los programas, entre todos podemos trabajar para hacer mejor software cada día

    Nos comentó richzendy, que El ha vivido del software libre durante 10 años, trabajando como capacitador, funcionario public y consultor, personalmente lo felicito y me parece un ejemplo a seguir.

    Pueden encontrar la presentación completa en el siguiente enlace.

    viernes, 27 de mayo de 2011

    Taller: Diseño usando herramientas libres

    Dictado por María "tatica" Leandro,

    En este taller tatica nos explicó como ella usa principalmente Inkscape para hacer diseños para banners, afiches o wallpapers.

    Básicamente nos dió varios consejos para trabajar de forma más sencilla y rápida:
    • Usar atajos de teclado: casi todos los atajos que más se usan, nos comenta tatica, tienen la siguiente forma: Ctrl+Shift+[Letra]. En especial el atajo Ctrl+Shift+F (fill) para definir el color de relleno (fill en ingles).
    • Colocar archivos, como imágenes, de uso común en un sitio web accesible, de este modo los tenemos a la mano donde sea que estemos y además podemos consultar información importante tal como colores.
    • Al trabajar con imprentas o medios de comunicación impresos considerar lo siguiente:
      * para afiches usar entre 150 a 300 dpi y enviar a la imprenta, en alguno de estos formatos: psd, pdf o tif.
      * para banners usar entre 120 a 170 dpi y enviar a la imprenta en formato: tif o tiff.

      Nota:Siempre es recomendable preguntar a la persona a la que enviaras el archivo cuales formatos le funcionan mejor

    • Siempre hay que considerar los costos de impresión y por ejemplo para imprimir un t-shirt es buena idea usar el color del mismo para el diseño. La regla es buscar la opción más económica pero por supuesto esto depende del presupuesto de cada quien.

    • Cuando estamos diseñando un wallpaper se debe considerar los siguientes aspectos:
      usabilidad, accesibilidad y apreciación.
      Cabe destacar que los iconos del escritorio, al menos en los escritorios tradicionales, aparecen a la izquierda por lo que un buen wallpaper tiene sus imágenes más grandes en el centro o a la derecha.


    • finalmente todas los artes que hagamos y coloquemos en el repositorio publico de Fedora, aunque no sea de inmediato, es muy probable que se use en el futuro, tal como nos contó tatica que le sucedió a ella con algunos afiches que creó hace unos años.


    Muy interesante esta presentación tatica, gracias!

    Saludos a todos.

    Icaro: Robotica educativa.

    Presentado por Valentín Basel (Argentina)

    Icaro es el nombre del gato de Valentín :D y es también un proyecto iniciado por El para enseñar a los niños sobre las diferentes
    disciplinas de la robótica, tales como: mecánica, electrónica, informática e inteligencia artificial.

    Con Icaro Valentín busca:
    • usar componentes o hardware de especificaciones libres
    • usar piezas de equipos reciclados (las impresoras son buenas fuentes de partes en especial motores)
    • usar hardware lo más simple y barato posible.
    • enseñar por medio del constructivismo o enseñar haciendo.
    • desarrollar software libre.
    Valentín nos comentó, durante la conferencia, que ha tenido experiencia en algunos colegios como El los denomina "urbanos-rurales" es decir:
    colegios mayormente publicos para personas de escasos recursos que de otro modo no tendría acceso a este tipo de tecnología.

    Para que este proyecto funcione Valentín programó un interprete que le permite a los niños, a quienes va dirigido este proyecto mayormente
    aunque sin excluir a nadie, programar sus robots casi sin conocer nada de programación.

    El interprete de icaro, nos cuenta su creador, está hecho en C++ y funciona con librerías estándar y muy básicas de modo que, en teoría, si
    tienes un equipo capas de correr un GNU/Linux eres capas de usar Icaro.

    Para más información por favor visitar el blog del proyecto.

    jueves, 26 de mayo de 2011

    FUDCon 2011 Panamá

    Un comienzo interesante tubo para mi este FUDCon, ayer pasé a buscar a Tatica, Richzendy y Gomix al aeropuerto de Tocumén.

    El primer día de conferencias ha estado bastante interesante con temas tales como: python, seguridad de red (iptables), robotica educativa (icaro), virtualización usando KVM y Documentación técnica.

    Pronto espero poder escribir un poco más en detalles sobre esas presentaciones.

    Saludos.

    lunes, 23 de mayo de 2011

    Como instalar Apache Archiva en Ubuntu

    Hoy estoy configurando en mi laptop Apache Archiva un administrador de repositorio para maven; Y bueno me pareció buena idea documentar el proceso en caso de que le sea de ayuda a alguien más o si me hace falta en el futuro.

    Instalación:
    1.) descargamos archiva stand alone, estoy usando la versión 1.3.4
    2.) Descomprimimos el archivo recientemente descargado.
    3.) Movemos la carpeta de archiva hacia donde será instalado finalmente, en mi caso en la carpeta opt.

    #1
    wget -c http://www.reverse.net/pub/apache//archiva/binaries/apache-archiva-1.3.4-bin.tar.gz
    #2
    tar xfv apache-archiva-1.3.4-bin.tar.gz
    #3
    sudo mv apache-archiva-1.3.4 /opt/
    

    Comprobamos que todo ha salido bien ejecutando en el siguiente comando:
    /opt/apache-archiva-1.3.4/bin/archiva console
    Abrimos el navegador web e ingresamos la dirección http://localhost:8080/archiva y deberíamos ver una pagina de configuración de la cuenta del administrador, si desean pueden rellenar los datos sino lo pueden hacer luego.

    Nota: Antes de continuar con la configuración debemos terminar el proceso presionando Ctrl+C en la consola donde lanzamos archiva.

    Configuración
    Ahora que ya esta instalado y funcionando lo siguiente es configurarlo.
    Para una mejor administración y actualización vamos a separar los datos y las configuraciones de la instalación de archiva:
    1.) creamos las carpetas necesarias.
    2.) copiamos los datos de la instalación actual de archiva a la carpeta de configuración.
    #1
    sudo mkdir -p /var/archiva/data
    sudo mkdir -p /var/archiva/conf
    sudo mkdir -p /var/archiva/logs
    
    #2
    cd /opt/apache-archiva-1.3.4/
    cp -v conf/* /var/archiva/conf/
    cp -vr data/* /var/archiva/data/
    

    Configurar Archiva como un demonio (daemon)
    1.) creamos un "start/stop" script en /etc/init.d/
    2.) modificamos el nuevo script para que lance archiva
    #1
    sudo touch /etc/init.d/archiva
    sudo chmod +x /etc/init.d/archiva
    #2
    sudo nano /etc/init.d/archiva
    

    Aquí les dejo mi script /etc/init.d/archiva como ejemplo.


    Nota: la variable de entorno ARCHIVA_BASE es necesaria para que archiva sepa de donde debe cargar los datos y las configuraciones

    Básicamente lo que hice fue:
    Definir o exportar la variable de entorno ARCHIVA_BASE igual a "/var/archiva".
    Pasar el primer parámetro al script en incluido en archiva con el que se puede lanzar el servidor muy fácilmente.

    Con esto podemos ejecutar los siguientes comando para lanzar o detener archiva.
    sudo /etc/init.d/archiva start
    sudo /etc/init.d/archiva stop
    

    Si deseamos que archiva se lance automáticamente al iniciar el sistema podemos ejecutar el siguiente comando:
    sudo update-rc.d archiva defaults
    
    Aquí pueden encontrar más información sobre el comando update-rc.d

    Algunos enlaces interesantes:

    * Apache Archiva: http://archiva.apache.org/
    * Archiva, guía de administradores: http://archiva.apache.org/docs/1.3.4/adminguide/index.html
    * Archiva 1.3.4 quick start: http://archiva.apache.org/docs/1.3.4/quick-start.html

    Saludos y será hasta la próxima.

    domingo, 22 de mayo de 2011

    Maven por consola de comandos en Ubuntu

    El otro día le explicaba a un amigo como usar maven y por cosas de la universidad donde estudia, me dijo que debía crear su proyecto sin la ayuda de ningún IDE; Por eso decidí hacer este tutorial para explicar la forma de crear aplicaciones en java usando maven desde la consola de comandos.

    Primero lo primero, hay que tener maven instalado, sino lo está ya la forma más simple es usando el siguiente comando:

    sudo aptitude install maven2
    Verificamos que este todo bien
    mvn --version

    Ahora que ya esta instalado maven, creamos nuestro proyecto, para este ejemplo crearé una aplicación Web usando el siguiente comando.
    mvn archetype:generate -DgroupId=net.ejemplos -DartifactId=ejemplo -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0-SNAPSHOT -DinteractiveMode=false
    

    Deberiamos ver una salida similar a la siguiente en la consola:
    [INFO] Scanning for projects...
    [INFO] Searching repository for plugin with prefix: 'archetype'.
    [INFO] ------------------------------------------------------------------------
    [INFO] Building Maven Default Project
    [INFO]    task-segment: [archetype:generate] (aggregator-style)
    [INFO] ------------------------------------------------------------------------
    [INFO] Preparing archetype:generate
    [INFO] No goals needed for project - skipping
    [INFO] [archetype:generate {execution: default-cli}]
    [INFO] Generating project in Batch mode
    [INFO] ----------------------------------------------------------------------------
    [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0
    [INFO] ----------------------------------------------------------------------------
    [INFO] Parameter: groupId, Value: net.ejemplos
    [INFO] Parameter: packageName, Value: net.ejemplos
    [INFO] Parameter: package, Value: net.ejemplos
    [INFO] Parameter: artifactId, Value: ejemplo
    [INFO] Parameter: basedir, Value: /home/[usuario]/Desarrollo
    [INFO] Parameter: version, Value: 1.0-SNAPSHOT
    [INFO] ********************* End of debug info from resources from generated POM ***********************
    [INFO] project created from Old (1.x) Archetype in dir: /home/[usuario]/Desarrollo/ejemplo
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 11 seconds
    [INFO] Finished at: Sun May 01 19:44:31 EST 2011
    [INFO] Final Memory: 11M/27M
    [INFO] ------------------------------------------------------------------------
    

    Luego creamos la carpeta donde ira nuestro código fuente y una primera clase simple:
    cd ejemeplo1
    mkdir -p src/main/java/net/ejemplos/
    touch src/main/java/net/ejemplos/DateTime.java
    gedit src/main/java/net/ejemplos/DateTime.java
    

    Dentro de la clase ponemos un código simple como por ejemplo el siguiente:
    package net.ejemplos;
    
    /**
     *
     * @author eivar
     */
    public class DateTime {
      public long getCurrentDate(){
        return System.currentTimeMillis();
      }
    }
    
    Nota: por favor reemplacen el autor con su nombre o eliminen el comentario :P

    Ahora podemos compilar o empaquetar el proyecto o cualquiera de las otras opciones que nos ofrece maven, por ejemeplo para compilar:
    mvn compile
    

    Ahora para probar nuestra clase modificamos el archivo index.jsp que debió haber sido creado automáticamente por maven:


    Ya que estamos trabajando con una aplicación web yo recomiendo usar jetty sobre todo porque se integra muy bien con maven mediante un plugin, a continuación dejo un ejemplo de mi pom.xml donde tengo configurado jetty:


    Ahora que tenemos integrado jetty y maven podemos usar el comando siguiente para compilar, empaquetar y ejecutar la aplicación desde la consola de comandos:
    #Presionamos ctrl+C para terminar la ejecution de jetty.
    mvn compile package jetty:run
    

    Recomiendo leer la documentación de maven aquí.

    Saludos.

    martes, 19 de abril de 2011

    Como sincronizar evolution con google

    Siguiendo un poco con el tema de conectar mis equipos a mi cuenta en google y sincronizar varios de los servicios de este último (por ejemplo gmail y google calendar), ahora escribo este post sobre como sincronizar evolution y google.

    Como referencia pueden leer aquí y aquí

    Estoy usando para esta configuración Ubuntu 10.10 con Gnome 2.32.0

    Pues bien manos a la obra:
    1. Suponiendo que es la primera vez que usamos Evolution, Vamos al menú Applicaciones->Oficina->Correo y calendario de Evolution automaticamente se iniciará el asistente de configuración de evolution, para que podamos agregar una nueva cuenta.
     
    2. El siguiente paso es rellenar los datos de la identidad de la cuenta: nombre, dirección de correo electrónico, etc. Por ejemplo la siguiente captura de pantalla:
    3. A continuación definimos los parámetros del servidor para la recepción de correo, el asistente detectó que estoy ingresando una cuenta de gmail y autocompletó los dos primeros campos, solo definí la encriptación como SSL y  "contraseña" como metodo de autenticación, queda en cada uno si desea que evolution recuerde su contraseña:
    4. Algunas opciones interesantes para activar o no según el criterio de cada uno se presentan en el siguiente paso, les dejo una captura de pantalla de mi configuración:
    5. De la misma forma que en el paso 3, en los parámetros de envío de correo solo tuve que elegir TLS como encriptación e "iniciar sesión" (login) como authenticación:
    6. Finalmente le damos un nombre a la cuenta, por ejemplo "Personal"
    Y listo, ya deberíamos ver los correos que llegan al gmail desde Evolution.

    En el próximo post hablaré sobre como sincronizar el Calendario y los Contactos de Evolution.

    Saludos.

    viernes, 15 de abril de 2011

    Problema con el teclado numerico Acer 5534

    Este es un pequeño problema que he tenido un par de veces en mi latop, una Acer 5534-1430 que tiene un teclado numérico (numpad) completo, algo poco común de acuerdo a mi experiencia.

    Cabe aclarar que estoy usando Ubuntu 10.10 y Gnome 2.32.0

    El problema
    Básicamente el teclado deja de funcionar y no importa que presiones muchas veces la tecla "Blog Num" para activarlo, no responde. Lo que pasa es que por alguna razón que el sistema usa este teclado para controlar el puntero del mouse y pues cuando presionas alguna tecla se traduce en un pequeño movimiento del puntero.

    La solución
    Aunque es un poco viejo, este enlace contiene la respuesta, lo que debemos hacer es:
    1) Ir a la preferencias del teclado en el menú Sistema->Preferencias->Teclado
    2) Seleccionamos el tab "Teclas del Ratón"
    3) Y desmarcamos la opción "Permitir controlar el puntero usando el teclado numérico".

    Listo!
    Con lo anterior su teclado numérico debería funcionar bien.

    Saludos.

    viernes, 8 de abril de 2011

    Como obtener especificaciones del computador por consola

    Esto empezó con una simple duda ¿cómo obtengo las especificaciones técnicas de mi pc?
    Tengo mala memoria así que no recuerdo en detalle si tengo pci express, ¿cuáles son los detalles de mi tarjeta gráfica? etc.

    Buscando un poco en internet encontré un post, en el que explican como usar el comando lshw.

    para obtener todos los detalles técnicos:
    sudo lshw
    

    podemos usar la opción -C para filtrar el resultado, por ejemplo para listar solo los discos duros:
    sudo lshw -C disk 
    

    algo que me parece muy interesante es la opción -html para exportar el resultado en formato html:
    sudo lshw -html > your-file-name.html
    

    domingo, 27 de marzo de 2011

    Nautilus Elementary en Ubuntu.

    Por recomendación de mi amigo Di3go me decidía a probar esta versión "parcheada" de nautilus en mi Ubuntu y aunque me falta mucho por aprender realmente me parece GENIAL por que se los recomiendo.

    Pueden encontrar más información acerca de nautilus-elementary aquí.

    A continuación los pasos para instalarlo en un bash script que pueden copiar y pegar en una terminal:

    #
    #1. agregamos el repositorio ppa.
    sudo add-apt-repository ppa:am-monkeyd/nautilus-elementary-ppa
    
    #2. actualizamos
    sudo apt-get update && sudo apt-get dist-upgrade
    
    #3. reiniciamos nautilus
    nautilus -q
    
    

    Adicionalmente pueden agregar "gloobus preview" el cual hace una perfecta combinación con nautilus-elementary (tomado de este post):
    #
    #1. agregamos el repositorio ppa.
    sudo add-apt-repository ppa:gloobus-dev/gloobus-preview
    
    #2. actualizamos en instalamos gloobus preview
    sudo apt-get update && sudo apt-get install gloobus-preview
    
    


    El post original, en ingles, en el cual me basé lo pueden encontrar aquí.

    Gracias a ammonkey por su trabajo :D

    Saludos y mucha suerte! :D

    miércoles, 9 de febrero de 2011

    La Crisis Crediticia Visualizada

    Es probable que ya sepan muy buen todo lo relacionado con la crisis crediticia que nos afectó a nivel mundial no hace mucho tiempo... ¿o no?

    Bueno espero que estos dos vídeos que les dejo a continuación les ayuden a entender, tal como me ayudaron a mi, porque es que se dio esta crisis...

    La Crisis Crediticia Visualizada - Parte 1


    La Crisis Crediticia Visualizada - Parte 2


    Mi conclusión esto pasó porque el ser humano es demasiado avaricioso :S :(

    Hasta la próxima.

    miércoles, 2 de febrero de 2011

    El poder de las expresiones regulares!

    En el trabajo se presentó una excelente oportunidad de comprobar el poder de las expresiones regulares o RegEx cuando un compañero estaba buscando una forma de formatear números en javascript. Básicamente lo que se quería era poder separar con una coma "," los miles, por poner un ejemplo:
    Dado el siguiente número:

    ejemplo 1 - número a formatear
    1000000.00
    transformarlo en la siguiente cadena:

    ejemplo 1 - número formateado
    "1,000,000.00"

    Encontramos las siguiente solución en StackOverflow

    ejemplo 2 - solución usando regex en javascript
    //fomat number using string.replace and regex
    function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(?:\d{3})+(?!\d))/g, ",");
    } 
    

    Esta sencilla y elegante solución me desconcertó e intrigó ¡no se me habría ocurrido! por lo que decidí investigar como funciona y aquí les dejo mi análisis y un port de ésto código a Java.

    El análisis.
    Primero veamos la definición de la función replace; pueden consultar otras funciones útiles que aceptan una regex como parámetro en javascript.

    ejemplo 3 - definición de la función String.replace
    /**
    * Replaces matches with the given string, 
    * and returns the edited string.
    */
    String.replace(pattern, string)
    

    Veamos el significado de la regex usada, como solía decir Fredcpp "vamos por partes":

    expresiónsignificado
    /marca el inicio y el fin de la expresión regular en javascript
    ()los paréntesis marcan el inicio y el fin de una supexpresión.
    \B"non-word boundary" selecciona una palabra es decir un conjunto de caracteres rodeado por espacios en blanco.
    (?=patrón), (?!patrón)"lookahead" prosigue solo si la expresión precedente es seguida por el patrón indicado

    (?=patrón) captura solo si existe un patrón a continuación.
    (?!patrón) captura solo si no existe un patrón a continuación.
    (?:patrón)busca el patrón completo pero no lo captura.
    \d{3}captura un patrón de 3 números seguidos, por ejemplo: 681
    patrón+indica que el patrón se puede repetir una o muchas veces.
    (?:\d{3})+captura un o varios grupos de 3 digitos
    (?!\d)captura si el siguiente elemento NO es un número


    Basándome en la tabla anterior, la expresión \B(?=(?:\d{3})+(?!\d)) captura todos los caracteres delante de uno o varios grupos de tres dígitos que no vienen seguidos de un número [1].

    La solución
    Antes de procesar el número debemos convertirlo en una cadena ("1000000.00").
    Entonces se usa la expresión para romper el número en un arreglo que consta de los siguientes elementos: ["1", "000", "000.00"]. Luego es solo cuestión de unir las partes usando una coma y obtenemos: "1,000,000.00" (asumo que esto último es lo que hace internamente replace)

    Potando el código a Java}
    Java soporta las mismas expresiones usadas en javascript por lo que esta función se puede escribir en java con algunos pequeños ajustes, quedando de la siguiente forma:
    //fomat number using String.replaceAll and regex
    public String numberWithCommas(Number number) {
        return number.toString().replaceAll("\\B(?=(?:\\d{3})+(?!\\d))", ",");
    }
    


    Hasta la próxima
    Notas:
    1. Si alguien tiene una mejor interpretación por favor compartirla.

    martes, 1 de febrero de 2011

    Anotaciones en XStream


    En un post anterior hablé sobre XStream. En este veremos como se pueden usar anotaciones en dicha librería.

    XStream soporta anotaciones que hacen las cosas un poco más simples, pueden encontrar más información aquí.

    Vamos a serguir trabajando con los POJOs del post anterior Person y PhoneNumber, pero ahora supongamos que el xml que debemos escribir tiene ciertas reglas, a saber:
    1. las etiquetas del xml para clase Person, cuando el nombre es una combinación de varias palabras, deben llevar separadas las palabras el caracter "_" sin las comillas.
    2. cuando un campo de tipo PhoneNumber sea serializado deberá llevar el atributo type con el valor "phone_number"

    Vamos a usar la anotación XStreamAlias que se puede aplicar tanto a clases como a campos dentro de una clase y elimina la necesidad de crear los alias individualmente para cada clase y cada campo dentro de ellas.

    ejemplo 1 - pojos usando anotaciones
    public class PhoneNumber {
      private int code;
      private String number;
      // ... constructores y métodos
    }
    
    @XStreamAlias("person")
    public class Person {
      @XStreamAlias("first_name") private String firstname;
      @XStreamAlias("last_name") private String lastname;
      private PhoneNumber phone;
      private PhoneNumber fax;
      // ... constructores y métodos
    }
    

    Por alguna razón que aun no termino de entender XStream reemplaza todos los "_" por "__" por lo cual debemos crear un nuevo XmlFriendlyReplacer.

    ejemplo 2 - creando un nuevo XmlFriendlyReplacer
    new XmlFriendlyReplacer("__", "_")
    

    La mejor forma que encontré para agregar el atributo type de acuerdo a las reglas dadas es crear una implementación de XppDriver.

    IMPORTANTE: debemos usar XStream con la librería XPP3.

    ejemplo 3 - creando una implementación de XppDriver
    new XppDriver(new XmlFriendlyReplacer("__", "_"))
    {
      @Override
      public HierarchicalStreamWriter createWriter(Writer out) 
      {
        return new PrettyPrintWriter(out, this.xmlFriendlyReplacer())
        {
          
          @Override
          public void startNode(String name, Class type) 
          {
            super.startNode(name, type);
            if (PhoneNumber.class.isAssignableFrom(type)) {
              addAttribute("type", "phone_number");
            }
          }
        };
      }
    }
    

    Ahora ponemos todo junto y obtenemos lo siguiente.

    ejemplo 4 - usando XStream con anotaciones y un nuevo XppDriver
    XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer("__", "_"))
    {
      @Override
      public HierarchicalStreamWriter createWriter(Writer out) 
      {
        return new PrettyPrintWriter(out, this.xmlFriendlyReplacer())
        {
          
          @Override
          public void startNode(String name, Class type) 
          {
            super.startNode(name, type);
            if (PhoneNumber.class.isAssignableFrom(type)) {
              addAttribute("type", "phone_number");
            }
          }
        };
      }
    });
    xstream.processAnnotations(new Class[]{Person.class});//[1] procesa todas las anotaciones
    xstream.autodetectAnnotations(true);//[2] habilita autodeteción de clases anotadas.
    
    Person joe = new Person("Joe", "Walnes");
    joe.setPhone(new PhoneNumber(123, "1234-456"));
    joe.setFax(new PhoneNumber(123, "9999-999"));
    String xml = xstream.toXML(joe);
    

    Si revisamos el contenido de la variable xml veremos que se ha generado un xml con las condiciones indicadas al inicio de este post.

    ejemplo 5 - contenido de la variable xml
    
      Joe
      Walnes
      
        123
        1234-456
      
      
        123
        9999-999
      
    
    


    Hasta la próxima. :D

    [Notas]
    1 Las anotaciones tienen la desventaja de que es necesario procesarlas antes de poder leer un archivo XML; Con processAnnotations nos aseguramos las clases pasadas como parámetro están listas para usarse tanto para leer como para escribir xml.

    2 autodetectAnnotations le permite a XStream autodetectar clases anotadas y automatizar su procesamiento pero debemos recordar que llamar al método processAnnotations desactiva esta funcionalidad.

    lunes, 31 de enero de 2011

    Como usar XStream en Java


    XStream es una interesante y simple libreria para serializar objetos a XML y viceversa.


    Caracteristicas de XStream
    • Fácil de usar. Cuenta una fachada de alto nivel que simplifica los casos más comunes de uso.
    • No requiere homologaciones “mappings”. La mayoría de los objetos se puede serilizar sin necesidad de crear archivos de homologación o “mapping”.
    • Rendimiento. Velocidad y bajo consumo de memoria son parte esencial del diseño, lo que hace que XStream sea adecuada sistemas con grandes objetos o alta demanda de envío de mensajes.
    • XML Limpio. XStream usa “reflection” y crea archivos XML facilmente entendibles por humanos y más compactos que usando la serialización nativa de Java.
    • No requiere modificar los objetos. Se serializan los campos internos, incluyendo privados y finales. Las clases internas y no publicas son soportadas. No se requiere que las clases tengan un constructor por defecto (sin parametros).
    • Soporte completo para objetos complejos. Las referencias duplicadas (duplicate references) encontradas en el objeto se mantienen. Soporta referencias duplicadas (circular references).
    • Integración con otras API de XML. Implementado un interfaz, Xstream puede serializar directamente hacia/desde cualquier estructura de arbol (tree structure) no sólo XML.
    • Estratégias de conversión personalizables. Las estrategias de conversión se pueden registrar permitiendo personalizar como los tipos son representados en XML.
    • Mensajes de error. Cuando una excepción, por XML mal formado, es encontrada se provee un diagnostico detallado para ayudar a encontrar y solucionar el problema.
    • Formato se salida alterno. El diseño modular permite otros formatos de salida. Xstream tiene actualmente soporte para JSON.


    Manos a la obra:
    Pueden consultar el tutorial de dos minutos en el cual me estoy basando para este post, con algunos detalles adicionales.

    Estoy omitiendo los constructores y métodos para ahorrar espacio ;-)
    Supongamos que tenemos los siguientes POJOs (Plain Old Java Object) :

    ejemplo 1 - pojos
    public class PhoneNumber {
      private int code;
      private String number;
      // ... constructores y métodos 
    }
    public class Person {
      private String firstname;
      private String lastname;
      private PhoneNumber phone;
      private PhoneNumber fax;
      // ... constructores y métodos
    }
    

    El siguiente es un ejemplo de como serializar un objeto tipo Person:

    ejemplo 2 - usando XStream
    XStream xstream = new XStream();
    //[1] alias opcionales
    xstream.alias("person", Person.class);
    
    Person joe = new Person("Joe", "Walnes");
    joe.setPhone(new PhoneNumber(123, "1234-456"));
    joe.setFax(new PhoneNumber(123, "9999-999"));
    String xml = xstream.toXML(joe);
    

    ejemplo 2.1 - contenido de la variable xml
    
        Joe
        Walnes
        
          123
          1234-456
        
        
          123
          9999-999
        
      
    

    Para convertir de XML a un objeto java:

    ejemplo 2.2 - xml a java.
    //usamos la variable xml del ejemplo 2
    Person newJoe = (Person)xstream.fromXML(xml);
    

    En el siguiente post hablaré sobre las Anotaciones en XStream.


    [Notas]
    1 Sino agregamos los alias opcionales el código aun funcionará pero los etiquetas de los elementos contendrán el nombre completo de cada clase (fully qualified name).

    Jetty Vs Tomcat

    Una interesante comparación entre Tomcat y Jetty

    viernes, 28 de enero de 2011

    Como sincronizar gmail con un smartphone

    El otro día estaba pensando sobre como sincronizar mi celular con mi cuenta de google, para tener un respaldo de mis contactos, tener mi agenda al día con google calendar y leer mis correos desde el celular, es decir estar en línea aun cuando estoy lejos de la oficina o la casa.

    Buscando un poco en Internet encontré varias alternativas para acceder desde el celular y me llamó la atención google sync el cual es bastante simple de configurar siguiendo estas instrucciones.

    Esta guía funciona con un Sory Ericsson Satio (Idou) pero si alguien tiene otro dispositivo de diferente y/o de otro fabricante puede consulta el siguiente enlace.

    Requerimientos:
    1. Celular con plan de datos (conexión a Internet), en mi caso un SE Satio.
    2. Una aplicación con soporte para el protocolo Microsoft® Exchange ActiveSync® ya que es el que usa Google Sync. En mi caso la usaré la aplicación RoadSync pre-instalada en el celular.
    3. Una cuenta en gmail.
    Procedimiento:
    1.  Iniciamos RoadSync y configuramos los parámetros de acuerdo a las siguientes instrucciones.
    2. En RoadSync tenemos la opción de sincronizar: correo electrónico, calendario, contactos y tareas, lastimosamente de acuerdo a la documentación de Google sync actualmente no está soportado sincronizar las tareas así que solo puedo activar las otras tres opciones.
    3. Tenemos la opción de programar la sincronización en un horario fijo (por ejemplo el horario de oficina), cada cierto tiempo o dejarla manual. Aquí cada quien elige lo que más le convenga.

    miércoles, 26 de enero de 2011

    Aplicación para twitter Beispanama

    Recientemente me enteré que un colega y amigo creó y liberó el código e una pequeña aplicación para Twitter para que los fanáticos del béisbol en Panamá podamos mostrar nuestro apoyo a nuestro equipo favorito.

    Felicito a @demogar por su trabajo e iniciativa de liberar el código para que otros podamos aprender de El.

    Vale la pena mencionar que la aplicación fue publicada en un sitio de noticias local, más información aquí.

    Beispanama fue diseñada y desarrollada por @demogar.
    Código liberado en GitHub y Bitbucket bajo licencia WTFPL.
    Made in Panama, ¡carajo!.

    viernes, 21 de enero de 2011

    http://admios.blogspot.com/2011/01/18-digit-case-safe-id-on-salesforcecom.html

    Today while doing a small test to check a Salesforce's API client I noticed that several objects returned by the API, has IDs of 18 characters which I found strange since they are supposed to be 15 letters and numbers, according to the API's documentation.

    For reference, an excerpt of the official documentation of salesforce:
    ID Field Type

    With rare exceptions, all objects in the API have a field of type ID that is named Id and contains a unique identifier for each record in the object. It is analogous to a primary key in relational databases...

    ID fields in the Salesforce.com user interface contain 15-character, base-62, case-sensitive strings. Each of the 15 characters can be a numeric digit (0-9), a lowercase letter (a-z), or an uppercase letter (A-Z). Two unique IDs may only be different by a change in case.

    With the aim of understanding why the ID returned by the API contain more than 15 characters did a little research and found the following:
    Because there are applications like Access which do not recognize that 50130000000014c is a different ID from 50130000000014C, an 18-digit, case-safe version of the ID is returned by all API calls. The 18 character IDs have been formed by adding a suffix to each ID in the Force.com API. 18-character IDs can be safely compared for uniqueness by case-insensitive applications, and can be used in all API calls when creating, editing, or deleting data.

    If you need to convert the 18-character ID to a 15-character version, truncate the last three characters. Salesforce.com recommends that you use the 18-character ID.

    Conclusion.
    So in essence, to prevent problems for those situations when case sensitive differences are not detected the API is returning 18-digits case-safe version of the ID.

    Hope this is useful to any of you.
    My original post