jueves, 29 de marzo de 2012

Karmacracy y como integrarlo en Blogger

Karmacracy
Hoy en día los que tienen un medio en el cual publican contenido ya se un blog, un periódico, agregador de noticias, foro u otra forma saben que añadir una barra de botones para que los usuarios puedan compartirlo es una buena idea ya que son los propios usuarios, a los que les parece interesante el contenido tanto como para compartirlo en alguna de sus redes sociales, los que ayudan a difundirlo. Esto es bueno para los medios ya que ayuda a atraer más visitas hacia ese contenido pero hasta el momento para los usuarios el hecho de compartirlo no tiene ningún aliciente adicional, lo más, formar parte de un número de usuarios que han compartido anteriormente.

Si habéis visitado este blog alguna otra vez tal vez os hayáis dado cuenta que debajo de cada entrada y de los tradicionales botones que ofrece blogger para compartir ha aparecido un bloque a través del cual también se puede compartir las entradas de una forma muy sencilla y en un par de clics en tus redes sociales como twitter, facebook o linkedin. Este bloque es proporcionado por Karmacracy, una herramienta que descubrí hace unos meses y ha sido ahora cuando me ha convencido para añadirlo por las ventajas que puede ofrecer tanto para un medio como este como para los usuarios que comparten el contenido en él.

Para el medio porque permite conocer a los usuarios que comparten cada contenido y ayuda a formar una comunidad de usuarios.

Para los usuarios porque muy probablemente les permita conocer usuarios con los mismos intereses y conseguir más contactos y seguidores en sus redes sociales, descubrir nuevo contenido de su círculo de usuarios que puede les interese, obtener estadísticas acerca del uso del contenido compartido y divertirse compartiendo al conseguir unos premios, llamados nuts, de los que hay más de 115.

En la página de base de conocimiento y ayuda se puede obtener toda la información para conocer en detalle Karmacracy y de su fórmula vitaminada para compartir y acortar URLs.

Si la información de esas páginas te convence también para añadirlo a tu blog ahora voy a explicar como añadirlo a blogger en cada entrada. Dentro de la administración del blog vamos a la sección de Plantilla, pulsamos sobre el botón Edición de HTML y pulsamos sobre continuar, buscamos un texto tal que <div class='post-footer'> en el widget Blog1. Esta sección del html de la plantilla es la parte que aparece debajo de cada entrada en el blog con lo que al final de la misma añadiremos el código del widget de karmacracy que hemos obtenido. Algo similar a lo siguiente, a fijarse son los atributos precedidos por expr: y data:.

Dado el poco tiempo que lleva karmacracy en El blog de pico.dev la mayoría de las entradas aún están vacías de usuarios pero listas a que impulséis su contenido, desde ahora os recomiendo que preferiblemente lo utilicéis ya que me permitirá conoceros y formar una pequeña comunidad que seguro será beneficiosa para todos.

Referencia:
Karmacracy

viernes, 23 de marzo de 2012

Herramienta de construcción Gradle

Gradle
Gradle es una de las muchas herramientas que existen para construir proyectos de forma automatizada pero tiene unas cuantas ventajas sobre otras que se han estado utilizado ampliamente hasta el momento como Ant y Maven en el mundo Java.

Primero vamos a ver los problemas de Ant y Maven. El problema de Ant es que para definir las tareas a ejecutar para la construcción del proyecto se utiliza XML y usar XML para describir las acciones de las tareas da resultado ficheros grandes y de difícil mantenimiento en cuanto el problema de la construcción es complicado. Otro problema es que Ant no tiene la noción de dependencias por lo que tendremos que descargarlas una a una, si posteriormente actualizamos a una nueva versión tendremos que volver revisar manualmente las dependencias que tengamos. Usando Ant con Ivy puede superarse esa dificultad. Por otra parte si tenemos varios proyectos relacionados y que dependen unos de otros la construcción de los mismos con Ant quizá no sea la herramienta más adecuada a día de hoy. A parte de esos problemas con Ant tendremos la sensación no solo de estar programando nuestro proyecto sino también la herramienta para la construcción del mismo.

Maven trata de solucionar varios defectos de Ant. En él se pueden definir las dependencias de un proyecto y Maven se encargará de descargarlas de forma automática incluyendo las dependencias que tengan estas a su vez, es decir, realizando la obtención de las mismas de forma transitiva. Además por defecto establece una serie de convenciones en cuanto a estructura de carpetas y sin que al contrario de Ant tengamos que describirla. Pero el problema de Maven empieza cuando necesitamos personalizar nuestra construcción llegando incluso a ser peor que en el caso de Ant. Los plugins de Maven suelen estar poco y mal documentados y tratar de hacer lo que queremos puede ser frustante y una pérdida de tiempo.

Gradle tiene varias de las ventajas de ambos sin poseer ninguna de sus desventajas comentadas. Posee la personalización de Ant, y la automatización de dependencias y convenciones de Maven además de un mejor soporte para la construcción de varios proyectos relacionados. Un de las primeras diferencias es que en vez de XML utiliza Groovy, un lenguaje mucho más adaptado a la tarea. Si estamos acostumbrados a Ant la migración no nos será muy complicada ya que desde Gradle podremos usar las tareas de Ant pero de una forma más cómoda que en XML al usar Groovy como lenguaje pudiendo incluso llamar a targets definidos en archivos XML de Ant. Una de las pegas que tiene es que es un poco lento en su inicialización y tal vez para tareas que usamos mucho y necesitamos que se ejecuten rápido sea más adecuado definirlas en Ant (con la opción --daemon de Gradle se soluciona en gran medida). Con tan solo definir el siguiente archivo estaremos listos para construir un proyecto web Java, en este caso para un proyecto Tapestry que utilice Hibernate, Quartz, FreeMarker, Java Mail, Groovy, HtmlUnit y Mockito:

description = 'Tapestry Project'
version = '0.0.1'

apply plugin: 'eclipse'
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'war'

// Propiedades de configuración
//Eclipse
downloadJavadoc = true

// Java
sourceCompatibility = 1.6

repositories { 
 flatDir name: 'Local', dirs: 'misc/lib'
 mavenRepo name: 'Apache (Staging)', url: 'https://repository.apache.org/content/groups/staging/'
 mavenRepo name: 'JBoss', url: 'https://repository.jboss.org/nexus/content/repositories/releases/'
 mavenRepo name: 'Java', url: 'http://download.java.net/maven/2/'
    mavenCentral()
}

dependencies {
 compile 'org.apache.tapestry:tapestry5-annotations:5.3.2'
 compile 'org.apache.tapestry:tapestry-core:5.3.2'
 compile 'org.apache.tapestry:tapestry-beanvalidator:5.3.2'
 compile 'org.apache.tapestry:tapestry-hibernate-core:5.3.2'
 compile 'org.apache.tapestry:tapestry-hibernate:5.3.2'
 compile 'org.apache.tapestry:tapestry-func:5.3.2'
 compile 'org.apache.tapestry:tapestry-ioc:5.3.2'
 compile 'org.apache.tapestry:tapestry-javadoc:5.3.2'
 compile 'org.apache.tapestry:tapestry-jmx:5.3.2'
 compile 'org.apache.tapestry:tapestry-json:5.3.2'
 compile 'org.apache.tapestry:tapestry-test:5.3.2'
 compile 'org.apache.tapestry:tapestry-upload:5.3.2'
 compile 'org.apache.tapestry:tapestry-yuicompressor:5.3.2'

 compile 'org.hibernate:hibernate-core:3.6.8.Final'
 compile 'org.hibernate:hibernate-ehcache:3.6.8.Final'
 compile 'org.hibernate:hibernate-validator:4.2.0.Final'

 compile 'org.quartz-scheduler:quartz:2.1.0'
 compile 'org.freemarker:freemarker:2.3.18'
 compile 'org.apache.commons:commons-lang3:3.0'

 providedCompile 'javax.servlet:servlet-api:2.5'
 providedCompile 'javax.mail:mail:1.4.4'

 groovy 'org.codehaus.groovy:groovy-all:1.8.3'

 // Test
 testCompile 'junit:junit:4.8.2'
 testCompile 'net.sourceforge.htmlunit:htmlunit:2.9'

 testCompile 'org.mockito:mockito-all:1.9.0'
}

Incluyendo los plugins de gradle eclipse, java, groovy y war algunas de las tareas que disponemos son:

  • eclipse: Genera los archivos para poder importar el proyecto en eclipse incluyendo todas las dependencias del proyecto.
  • clean: limpia los archivos tenporales creados por gralde en la ejecución de las tareas.
  • classes: compila los archivos fuente de java, además haciendo uso del plugin de java tambien se compilan los archivos de codigo fuente de groovy.
  • javadoc: crea la documentación de javadoc de los archivos del proyecto.
  • jar: crea un jar con los archivos fuente de java.
  • war: crea un war del proyecto.

Para ver la estructura de directorios consultar la documentación de cada uno de los plugins:


La cantidad de plugins para gradle va en aumento. Algunos de los más útiles son: checkstyle, codenarc, pmd, tomcat, jetty.

Para instalarlo basta con descargar sus binarios, descompromirlos en una carpeta y crear una variable de entorno para $GRADLE_HOME. Una vez hecho esto su uso es similar al de ant y maven, nos colocamos en el directorio donde está el archivo .gradle y ejecutamos:

$GRADLE_HOME/bin/gradle [tarea]

Si queremos tener una experiencia de uso más agradable con gradle es muy útil usar su modo demonio ya que de otra manera tarda en cargarse bastantes segundos, si lo usamos cada poco tiempo y muchas veces aunque luego el tiempo de las propias tareas sea poco notaremos que perdemos tiempo esperando. Para evitarlo añadimos el parámetro --daemon, notaremos mucha diferencia respecto a lo se tarda en cargarse sin él y la ejecución de nuestras pequeñas tareas serán mucho más rápidas.

$GRADLE_HOME/bin/gradle --daemon [tarea]


La diferencia es notable de casi 12 segundos a casi 5, un poco menos de la mitad.

Referencia:
http://www.gradle.org/
http://www.gradle.org/current/docs/userguide/userguide.html
Usar Gradle mediante Gradle wrapper

http://ant.apache.org/
http://maven.apache.org/
http://ant.apache.org/ivy/

viernes, 16 de marzo de 2012

Patrones de diseño en la programación orientada a objetos

Java
La programación orientada a objetos (POO) es un paradigma en la que los sistemas se diseñan mediante clases y relaciones entre ellas. Se utilizan conceptos como la herencia, polimorfismo, abstración, encapsulamiento y ocultación. Resumidamente estas propiedades son:
  • Clase: Abstracción que recoge las propiedades y comportamiento de los objetos en el sistema. Una clase puede instanciarse en objetos tantas veces como se necesite.
  • Objeto: instancia de una clase que se relaciona con el resto de objetos a través de los métodos definidos en sus clases.
  • Herencia: las clases no están aisladas y se relacionan entre ellas, mediante esta propiedad forman una jerarquía en la que las clases heredan las propiedades y métodos de las clases superiores.
  • Polimorfismo: es la propiedad de las instancias de las clases, los objetos, por la que pueden responder de forma diferente a un mismo nombre de método en función de su tipo concreto.
  • Abstracción: Permite modelar una entidad del ámbito de trabajo con las características relevantes para el sistema.
  • Encapsulamiento: los elementos relacionados se agrupan juntos en una misma clase para aumentar la cohesión.
  • Ocultación: las clases tienen una interfaz a través de la cual el resto de clases interactuan con ella de forma que no necesiten conocer sus detalles y evita que clases externas modifiquen el estado de manera inesperada.
Conocer estas propiedades es importante para programar en un lenguaje orietado a objetos sin embargo no es suficiente para diseñar sistemas que sean fáciles de mantener y que permitan adaptarse a nuevos cambios sin rediseñar los sistemas.

Aquí es donde aparecen los patrones de diseño y unos principios a la hora de diseñar los sistemas OO. Los patrones de diseño son formas identificadas que resuelve de forma correcta diferentes problemas comunes a algunos escenarios. Los principios son unas guías que dirigen el diseño que realizamos y que en gran medida están presentes en los patrones de diseño.

Muy resumidamente los patrones de diseño tienen como objetivo permitir hacer frente a toda constante que posee cualquier aplicación, el cambio, de tal forma que permitan escalar a los sistemas incorporando nuevas funcionalidades y prefiriendo añadir nuevo código a modificar código existente.

Algunos principios que deberían guiar nuestras decisiones son:
  • Encapsula lo que varía
  • Favorece la composición sobre herencia
  • Programa sobre interfaces, no implementaciones
  • Abierto a extensión, cerrado a cambio
  • Depende sobre abstracciones, no sobre clases concretas
  • Conocimiento solo de clase amigas
  • No nos llames, nosotros te llamaremos
  • Una clase debería tener solo una razón para cambiarla
  • Inversión de dependencias
Algunos patrones identificados y que resulven de forma correcta algunos problemas son:
Un muy buen libro que recoge todos estos principios y patrones es «Head First Design Patterns » y en el que se describe de forma más detallada y con ejemplos la aplicación de los principios y el uso de los patrones de una forma sencilla y bien explicada. Aunque es un libro con los ejemplos en Java es una lectura muy recomendada para cualquiera que quiera subir un nivel como desarrollador.


Después de leer el libro es buena idea tener una hoja de referencia con todos los patrones, en DZone hay una disponible que se puede descargar libremente design patterns cheat sheet. Si no quieres registrarte para descargarla usa Bug me not.

Referencia:
Programación orientada a objetos (Wikipedia)
Libro Head First - Desing Patterns de O'Reilly
Ejemplo del patrón de diseño Command y programación concurrente en Java
Ejemplo del patrón de diseño State
Ejemplo del patrón de diseño No Operation

viernes, 9 de marzo de 2012

Guía post instalación Minix

Minix
Hace ya un tiempo escribí un par de entradas sobre el sistema Minix porque tiene algunas características muy interesantes que ya les gustaría tener a otros sistemas operativos, El sistema operativo Minix donde daba una descripción de él y una Guía de instalación Minix donde explicaba como era su instalación en una máquina virtual con VirtualBox. Ahora con la reciente salida de la versión 3.2.0 de Minix y la adición de nuevas características escribo esta entrada para saber que hacer después de instalarlo con el objetivo de intentar hacer de Minix usable para algo y no quedarme con la sensación de que es algo experimental (aunque aún tengo la sensación de ello).

Los paquetes disponibles para Minix no son muchos y por tanto las posibilidades están limitadas pero en esta entrada voy a explicar algún uso útil que le podríamos dar a Minix.


Cambiar la contraseña al usuario root
Una de las primeras cosas que deberíamos hacer después de instalarlo es cambiar la contraseña del usuario root con:

# passwd

Cambiar la zona horaria
Modificaremos la zona horaria. Para ello añadimos al archivo /etc/rc.tomezone lo siguiente:
export TZ=Europe/Madrid

Crear un usuarios y grupos
Dado que Minix casi seguro no será nuestro sistema principal no nos preocupará mucho la seguridad pero deberíamos estar acostumbrados a no trabajar con la cuenta del superusuario root. Para ello podemos crear un grupo (wheel), un usuario (minix) para usarlo de forma normal en tareas no administrativas, le cambiamos de contraseña al usuario y el nombre completo del usuario (o algunos otros datos).

# group add wheel
# user add -m -g users minix
# passwd minix
# chfn minix

Editores, navegador web, correo electrónico, transferencia de archivos
Vim es un editor muy versátil y aunque el paquete de Minix no sea la última versión nos ayudará a trabajar de forma más cómoda. Hay otros editores como ed, nano y elvis. Los instalamos con el gestor de paquetes de minix, pkgin. Otros programas de utilidad básicos con un navegador web (links), un programa para enviar y leer los correos electrónicos (mutt) y programas para la trasnferencia de archivos (ftp y curl).

# pkgin install vim
# pkgin install links
# pkgin install mutt
# pkgin install curl


Servidor web, Python, OpenSSH
Si somos desarrolladores y queremos desarrollar algo básico tenemos a nuestra disposición algunos paquetes que nos lo permitirán. Estos son un servidor web (apache), el lenguaje de programación python, también podremos desarrollar programas en c, y una herramienta para conectarnos a la máquina minix de forma remota a través de ssh (OpenSSH).

Para iniciar el servicio de apache en minix ejecutarmos:

# /usr/pkg/sbin/apachectl start

Aquí podemos ver la página de bienvenida devuelta Apache y servida por la máquina minix y el típico hola mundo programado en Python y su ejecución en Minix.

# pkgin install apache
# pkgin install python
# pkgin install openssh

Juegos
También hay disponibles algunos juegos, en modo texto. Dungeon es una aventura donde iremos obteniendo una descripción de las habitaciones por donde vamos pasando y podremos realizar acciones introduciendolas en texto. gnugo es un juego de tablero del juego go donde deberemos controlar la mayor parte posible del mismo. En aop deberemos dirigir mediante las fechas del teclado un caracter que nos representa a otro punto de la pantalla evitando los obstáculos.

# pkgin install dungeon gnugo aop


Desde luego Minix no dispone de la cantidad de herramientas de otros sistemas y tampoco en sus últimas versiones, tiene casi la categoría de exprimental pero como vemos hay algunos usos que le podemos dar.

Referencia:
El sistema operativo Minix
Guía instalación Minix
http://wiki.minix3.org/en/UsersGuide/PostInstallation
http://wiki.minix3.org/en/UsersGuide
http://wiki.minix3.org/en/UsersGuide/ManagingUserAccounts
http://wiki.minix3.org/en/DevelopersGuide

viernes, 2 de marzo de 2012

Conversiones de datos entre el cliente y servidor en Apache Tapestry

Apache Tapestry
Las clases que implementan la interfaz Translator en Tapestry permiten convertir el valor de un campo de texto a un objeto (a través del método parseClient) y de un objeto a un texto que será incluido en un elemento de formulario en el cliente (a través del método toClient). Esta conversión es necesaria ya que lo que enviamos al cliente y lo que recibimos de él es un String. Al recibir los datos desde cliente en el servidor necesitaremos alguna forma de convertir esos datos representados en formato texto a su representación en objeto que hagamos en el el servidor. Estas dos tareas que en un principio no son muy complejas son tremendamente necesarias y básicas en cualquier aplicación web, siendo algo básico es el framework que usemos el que debería dar un buen soporte para estas tareas. Con los translators podremos evitar repetirnos en diferentes puntos de la aplicación.

Una vez que tengamos definido el translator, Tapestry buscará el adecuado según el tipo de objeto a traducir y lo usará según sea necesario sin necesidad de que tengamos que hacer nada más. Vamos a ver un ejemplo, supongamos que en un campo de un formulario necesitamos mostrar una fecha con un determinado formato. En nuestras clases trabajaremos con objetos de tipo Date. El usuario deberá introducir la fecha con formato «dd/MM/yyyy».

...
import org.apache.tapestry5.internal.translator.AbstractTranslator;
import org.apache.tapestry5.services.FormSupport;

import com.evandti.ticketbis.domain.CodigoDescuento;
import com.evandti.ticketbis.misc.Utilidades;
import com.evandti.ticketbis.tapestry.services.TicketbisService;

public class DateTranslator extends AbstractTranslator<Date> {

 private String patron;

 public DateTranslator(String patron) {
  super("date", Date.class, "date-format-exception");
  this.patron = patron;
 }

 @Override
 public String toClient(Date value) {
  if (value == null) {
   return null;
  }
  
  return new SimpleDateFormat(patron).format(value);
 }

 @Override
 public Date parseClient(Field field, String clientValue, String message) throws ValidationException {
  if (clientValue == null) {
   return null;
  }

  try {
   return new SimpleDateFormat(patron).parse(clientValue);
  } catch (ParseException e) {
   throw new ValidationException(message);
  }
 }

 @Override
 public void render(Field field, String message, MarkupWriter writer, FormSupport formSupport) {
 }
}

Estamos extendiendo una clase del paquete org.apache.tapestry5.internal que es algo no recomendado pero la utilizamos por sencillez y para no tener que implementar nosotros lo que hace el propio AbstractTranslator. Para que Tapestry lo utilice deberemos hacer una contribución en el módulo de nuestra aplicación donde básicamente decimos que para una determinada clase se utilice un determinado Translator.

/* AppModule.java */
 public static void contributeTranslatorSource(MappedConfiguration configuration) {
  configuration.add(Date.class, new DateTranslator("dd/MM/yyyy"));
 }

A partir de este momento podríamos tener en archivo .tml de una página o componente lo siguiente y en la propiedad fecha del componente o página tendríamos un objeto de tipo Date olvidándonos por completo de la traducción.

<t:label for="fecha"/>: <t:textfield t:id="fecha" value="fecha" size="12" label="Fecha"/>

Hay otra interfaz que hacen algo similar a los Translators, es la interfaz ValueEncoder pero la diferencia entre las dos está en que en los translators puede ser necesaria algún tipo de validación por nuestra parte ya que son datos que introduce el usuario y en los encoders no ya que no son datos que introduce el usuario. Esto se ve claramente en los parámetros de los componentes TextField, Hidden y Select, el primero utiliza un Translator y los dos últimos un ValueEndoder.

Tapestry ya proporciona un ValueEncoder para las entidades de nuestro dominio si utilizamos Hibernate, la clase es HibernateEntityValueEncoder. Para terminar, indicar Tapestry también proporciona un ValueEncoder por defecto para los tipos Enum.

Referencia:
Documentación sobre Apache Tapesty