jueves, abril 29, 2010

ScrumNinja: herramienta para la gestión de equipos con Scrum

Si gestionas tus proyectos con Scrum, aquí tienes una nueva herramienta que promete facilitarte las tareas de mantenimiento de los diferentes artefactos a mantener (Project Backlog, Sprints, User Stories, ...): ScrumNinja.

Disponen de dos diferentes modelos de explotación: hosting o software instalable. En el primer caso, los pagos son mensuales y dependen del numero de usuarios. En el segundo caso, se realiza un único pago en función del número de usuarios. Los precios son bastante asequibles.

Incluye herramientas visuales, como la pizarra de Scrum.

Puedes probarlo de forma gratuita durante 30 días.

Netbeans 6.9 Beta ya disponible

La beta del IDE Netbeans 6.9 ya está disponible para su descarga.

Incluye mejoras referentes a OSGi, JavaFX (editor visual similar al de Swing), PHP (soporte para Zend Framework), soporte para Ruby on Rails 3.0, soporte para Spring Framework 3.0.

Esta es la lista de todas las novedades:
http://netbeans.org/community/releases/69/

Y el enlace para descargarlo:
http://download.netbeans.org/netbeans/6.9/beta/

miércoles, abril 28, 2010

Cómo eliminar definitivamente una cuenta en facebook

Por si en algún momento quieres eliminar completamente tu cuenta de facebook:

Si entras en tu cuenta, en la configuración de la cuenta podrás ver que existe la posibilidad de desactivarla, pero aparentemente no hay una opción de eliminar tu cuenta definitivamente. Sin embargo esta opción existe. El enlace es el siguiente (tienes que estar logueado en la cuenta que deseas eliminar):

http://www.facebook.com/help/contact.php?show_form=delete_account


El procedimiento es rápido y te informan que tu cuenta pasa a estar desactivada y que se eliminará completamente en unos 14 días. También te informa que durante esos 14 días puedes entrar en cualquier momento y volver a activar tu cuenta, con lo cual se cancelará el proceso de eliminación.

A continuación te envían un correo a la dirección asociada a la cuenta con el título "Cuenta programada para su eliminación" (esto me suena a Star Wars, episodio IV), con el siguiente contenido:

"Hola, XXXXXXXXXXX:

Hemos recibido una petición para eliminar tu cuenta de Facebook permanentemente. Tu cuenta está ya inhabilitada y será eliminada de forma permanente en los próximos 14 días.

Si no deseas eliminar tu cuenta, haz clic en el siguiente enlace para cancelar la petición:

http://www.facebook.com/account_delete.php

Gracias,
El equipo de Facebook"

miércoles, abril 07, 2010

¿Por qué no funciona la etiqueta s:if al comparar con cadenas?

Usando Struts 2 me he encontrado con un problema que, a simple vista, no debería serlo.

Usando la etiqueta <s:if...> intentaba comparar el valor de una propiedad de un objeto en el ValueStack (proveniente de un action a través del ModelDriven) y una cadena. En concreto un 'N'.

Pero nunca llegaba a cumplirse la condición. Me aseguré de que la propiedad tuviera el valor adecuado, pero aún así, nada. El código que usaba era este:


<s:if test="%{nombre_propiedad eq 'N'}">...


La solución la encontré aquí. El problema es que ONGL no interpreta correctamente los char como string. La solución, hacer que compare con cadenas (entre comillas dobles) y no con caracteres (comillas simples):


<s:if test='%{nombre_propiedad eq "N"}'>...


Espero que os sirva.

martes, abril 06, 2010

JPA: Modificar unidades de persistencia programáticamente

Si trabajáis con JPA, nosotros concretamente con Netbeans (aunque en Eclipse funciona de forma similar), durante el desarrollo de las aplicaciones, procedemos a crear un modelo de datos y a desplegar el modelo físico sobre nuestro motor de base de datos.

En el caso de Netbeans, mediante wizards, creamos nuestra conexión, la unidad de persistencia ("persistence.xml") y podemos generar nuestras entidades a partir del modelo físico.

¿Y el proceso inverso?. Supongamos que ya tenemos nuestra aplicación y lo que queremos es que al desplegar nuestra aplicación en los servidores de producción, en base a nuestras entidades, se recree la base de datos, sin necesidad de hacer una importación (debe existir el esquema y el usuario, por supuesto, pero no es preciso importar las tablas "manualmente").

Esto es posible modificando programáticamente una unidad de persistencia existente en el archivo "persistence.xml". Con un poco de trabajo, se puede crear un "wizard" en nuestra aplicación que detecte si la instalación es nueva y que sea capaz de recrear las tablas en base a nuestras entidades ya existentes.

Al menos, esta es la forma que hemos encontrado de hacerlo... es posible que haya formas mejores.

(Este ejemplo enlaza con el post anterior sobre el motor InnoDB de MySQL. En nuestro caso, las tablas originales eran InnoDB, pero cuando se recreaban las tablas en otro esquema, aparecían como MyISAM.)

En el ejemplo, uso TopLink Essentials, de Oracle. Las propiedades para Hibernate o EclipseLink, varían.

Este sería nuestro archivo "persistence.xml". Como véis, no tiene propiedades. Sólamente declaramos el nombre de la unidad, el proveedor y las entidades, pero no las propiedades:


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="PersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>test.entities.Entidad2</class>
<class>test.entities.Entidad1</class>
</persistence-unit>
</persistence>


Modificar la unidad de persistencia pasando las propiedades programáticamente, es simple:


Properties props = new Properties();
props.put(TopLinkProperties.JDBC_USER,"user");
props.put(TopLinkProperties.JDBC_PASSWORD,"password");
props.put(TopLinkProperties.JDBC_URL,"jdbc:mysql://hostname:3306/targetddbb?sessionVariables=storage_engine=InnoDB");
props.put("toplink.ddl-generation","create-tables");
props.put(TopLinkProperties.JDBC_DRIVER,"com.mysql.jdbc.Driver");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersistenceUnit",props);
EntityManager em = emf.createEntityManager();
em.close();
emf.close();


Si os fijáis, hay una propiedad "toplink.ddl-generation", con el valor "create-tables". Esto hace que al instanciar el objeto EntityManager, se regeneren las tablas en la base de datos, en base a las entidades declaradas en "persistence.xml" y asociadas a la unidad "PersistenceUnit". Es decir, sólo con ejecutar este código, se regeneran las tablas.

Por último insistir en que para realizar las pruebas, hemos usado:

- Netbeans 6.8
- TopLink Essentials
- MySQL

Los esquemas de origen y destino de nuestras tablas eran MySQL. No hemos probado a regenerar las tablas en una base de datos distinta...

MySQL: forzar la creación de tablas InnoDB

Hola a todos,

es posible que en alguna ocasión al crear nuevas tablas en MySQL os encontréis con que por defecto las tablas se crean con el motor MyISAM, en lugar de InnoDB. Esto ocurre porque en la instalación del servidor se ha seleccionado MyISAM como motor por defecto.

La primera solución que se nos puede ocurrir es modificar la configuración de MySQL para que el motor por defecto sea InnoDB. Esto tiene sus inconvenientes, ya que en un entorno de producción modificar la configuración del servidor puede ser un problema.

Sin embargo, hay una solución muy simple y que evitará que nos peleemos con el administrador de turno. En la propia cadena de conexión de MySQL, podemos pasar parámetros adicionales que modifican la forma en que el servidor se comporta para dicha conexión. El detalle de estos parámetros se puede consultar aquí (es para la versión 5.5, pero existen para versiones anteriores):

http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html

El parámetro que nos interesa se llama "sessionVariables". En este parámetro se puede pasar múltiples valores separados por coma que determinan el funcionamiento de la sesión de MySQL.

En concreto para forzar que el motor por defecto durante nuestra sesión sea InnoDB, deberíamos crear una conexión de este tipo:

"jdbc:mysql://hostname:3306/ddbbname?sessionVariables=storage_engine=InnoDB"

De esta manera, cualquier sentencia "CREATE TABLE" creará tablas InnoDB aunque el motor por defecto sea otro.