Publica tu how-to

Dinos como hacer lo que sabes hacer, mándanos un email a wdonet@gmail.com y lo publicamos (dos días máximo) o si te interesa unirte al equipo de redactores, también háznoslo saber por correo.

GIT - Vista Rapida Comandos

Para crear un Branch
git checkout -b newLocalBranch
git push -u origin newLocalBranch

Uso de checkout
branch (cambiar de branch a branch):
     git checkout remoteBranch
Para restaurar al archivo original (olvidar cambios):
     git checkout path/local/file

Watering - traerte los cambios del branch origen a tu branch actual 
git merge origin/master --no-commit
git commit  -m"watering"
git push

Cherry pick - traerte los cambios de un commit a tu branch actual
1. git cherry-pick #hash
2. git push

Hacer un merge de un branch sobre master (o el origen de donde surgio el branch)
git checkout {upstream-branch-name}
git pull
git merge --squash --no-commit origin/{branch-to-merge}
git commit
mvn clean install
ant test.js.all
git push

Borrar un branch
git branch -rd origin/remoteBranchName (forzar a borrarlo cuando no tienes una copia localmente)
or
git branch -D localBranchName
git push origin :remoteBranchName

Esconder cambios con stash
ver lista de cambios escondidos:                         git stash list
ver cambios de un elemento de la lista:              git stash show stash@{#}   
esconder cambios como uno en la lista:              git stash save "Some stash message here”
aplicar cambios al branch sin borrar de la lista:   git stash apply stash@{#}
aplicar cambios y eliminarlos de la lista :            git stash pop stash@{#}
borrar un elemento de la lista :                            git stash drop stash@{#}
borrar todos los elementos de la lista:                 git stash clear

Revertir cambios de un branch remoto (o ya pusheados)
git revert #exactlyTheRemoteHashOfInterest —no-commit

Resetear cambios del branch local (commiteados pero no pusheados)
1. buscar el #hash previo (no el hash que estas interesado en resetear, sino uno antes)
git log
2.1 resetear (todos los commits van a ser devueltos a la bandeja de unstage - antes de comitear)
git reset #localHash
2.2 O tambien puedes deshacer el commit N (con HEAD~N) y perder los cambios (con --hard)
git reset --hard HEAD~1
2.3. Si quieres deshacer cambios pero no perderlos (que por default usa --soft)
git reset HEAD~1

Patron de Diseño Command

El patrón comando permite que solicitudes del cliente sean encapsuladas como objetos, indicar parámetros a diferentes solicitudes, encolarlas, registrarlas y hasta dar soporte para operaciones des-hacer.



Participantes:
  1. invocador (invoker) - el que almacena las ordenes y las manda ejecutar.
  2. cliente (client) - el que proporciona la orden al invocador.
  3. receptor (receiver) - aquél que en verdad realiza la acción que se mandó a ejecutar
  4. comando (command) -la orden que relaciona al invocador con el receptor de manera general
  5. comando concreto (concrete command) - la implementación para la ejecución de la orden (es más específica)

Ejemplo:
  • El consumidor (cliente) da órdenes (comandos) a un mesero (invocador), el cuál las apila para después pasarla al cocinero (ejecutar la acción).  El cocinero (receptor) entonces realiza la acción.
  • El usuario abre su programa favorito (cliente) , da clic sobre el contenedor de comandos llamado "menú Archivo" (invocador) y después sobre abrir archivo (comando), el cual abre una segunda ventana para indicarle de que archivo se trata (receptor). Cada opción del menú archivo ejecuta una acción que es un comando parametrizado.
Consecuencias:
El objeto que invoca el comando y el que lo realiza están des-acoplados. El invocador no tiene por que saber de que forma se ejecuta la acción.
Los objetos comandos se pueden extender usando patrones como Composite y Memento.
Es fácil agregar comandos porque no tienes que modificar las clases ya hechas.

Decisiones de diseño:
  • Cuando quieras parametrizar objetos que realicen una acción determinada
  • Cuando necesites encolar y ejecutar una serie de solicitudes en diferentes momentos
  • Si deseas mantener un historial de ejecuciones para así permitirte des-hacerlas, también es sencillo logear cada proceso de manera que si falla el sistema, se pueda saber en que punto quedó para una restauración manual.

Aceleración del Emulador Android en Linux

Apenas me estoy metiendo a jugar un poco para programar en Android y me topé con el problema de que el emulador va lentísimo en Linux. Cabe notar que el Android SDK Manager tiene un paquete que menciona la aceleración del emulador en Intel, pero explícitamente dice: "NO SOPORTADO EN LINUX". Lo cual no significa que todo esté perdido ;-)

Investigando me topé con este hilo en stackoverflow: http://stackoverflow.com/questions/1554099/slow-android-emulator

Que hace referencia a esta información del sitio de Intel: http://software.intel.com/en-us/blogs/2012/03/12/how-to-start-intel-hardware-assisted-virtualization-hypervisor-on-linux-to-speed-up-intel-android-x86-gingerbread-emulator

En resumen, hay que instalar Qemu (para virtualización en Linux usando KVM), y puesto que el emulador de Android se basa en Qemu, es sólo cuestión de ligarlos.

Hecho eso, se puede crear un AVD que utilice como CPU/ABI un Intel Atom (x86), y que al emular se debe usar el host del GPU. Si emulas vía la consola, debes usar emulator-x86 con las opciones -qemu -m 2047 -enable-kvm

Voilá, tu emulador debería de volar ahora...

Issues con los que me topé:
-Al instalar los módulos del kernel de KVM hay que asegurarse que la virtualización no esté deshabilitada en la BIOS. (Y ya con esto tengo para virtualizar lo que quiera! suelo usar virtualbox, luego jugaré con esto también :D )
- No hay que olvidar que se debe instalar también la imagen Intel X86 en el Android SDK Manager

Hacer Push de un branch local a un repositorio Git remoto

Tan simple como usar git push con el nombre del branch.
Digamos que tenemos un branch plugin que queremos subir al repositorio origin:

git push -u origin plugin

El parámetro -u permite crear un upstream en donde sea que bajemos este branch desde origin, de forma que hacer push/pull sea mucho más sencillo.

Para bajar este branch desde el repositorio, bastaría hacer:

git fetch origin

[Git nos informará que se ha creado un nuevo branch, origin/plugin]

git checkout --track origin/plugin

Con esto cambiamos al nuevo branch, y además le damos seguimiento para hacer actualizaciones de manera rápida y sencilla cuando hagamos push.

Como agregar una libreria al codigo manualmente (jQuery)

function loadJQuery() {
                var fileref = document.createElement('script');
                fileref.setAttribute("type", "text/javascript");
                fileref.setAttribute("src", "http://code.jquery.com/jquery-1.5.min.js");
                document.getElementsByTagName('head')[0].appendChild(fileref);

}();

Fácil no? .. Puedes cambiar la version si deseas otra de jQuery o bien , la URL completa para cualquier otra libreria.

Por otro lado, si ya la cargaste previamente en el render de tu documento, no olvides poner tu código dentro de ready:

$(document).ready(function() {
// Handler for .ready() called.
});

2 configuraciones con Spring Mail para usar Gmail

He notado que la configuración de la clase "JavaMailSender" de Spring es un poco confusa para algunos y personalmente me ocurrió cuando al principio tomé el proyecto de enviar correos con Spring.

Así que dejo aquí, dos configuraciones que me funcionaron a la perfección con Gmail: TLS y SSL

Debo hacer notar que también funciona con Google Apps for Business.

Entorno No Integrado de Desarrollo (UDE)


Casi todos los desarrolladores que conozco acostumbran utilizar herramientas pesadas para hacer su trabajo.

Una de dichas herramientas, el IDE (entorno de desarrollo integrado) suele ser un programa grande que incluye en un sólo paquete las herramientas más comunes que un desarrollador puede llegar a necesitar.

Ese es el problema: asumir que el desarrollador VA a necesitar las herramientas, cuando en realidad sólo PUEDE que las necesite.

Por esa razón, tiene un tiempo ya que no utilizo IDEs para mi trabajo. O como leí alguna vez, utilizo un entorno NoIntegrado de Desarrollo (Unintegrated Development Environment).

Armar un entorno así no es nada difícil, y sólo requiere de un conocimiento concisio de las herramientas que en realidad tiene a su disposición un programador para hacer su trabajo, según el sistema sobre el que trabaje.


Como subir un proyecto con GIT a GitHub

Para subir un proyecto a gitHub no hay mas que seguir los mismos tutoriales que te proveen pero a resumidas cuentas tienes que hacer lo siguiente:

1.- Crear una cuenta en GitHub

 Tienes que ir a la liga : https://github.com/plans y darle en el botón de Create a free Account, una cuenta libre te permite tener tantos repositorios públicos y colaboradores públicos como quieras, pero ninguno privado, si quieres esto, tienes que pagar.

Este paso es muy rápido y obvio, después de ingresar tus datos recibirás un mail de confirmación y listo, regresas a la página para entrar a tu cuenta.

2.- Instalar Git en tu equipo 

En windows puedes descargar una versión de Git desde : http://code.google.com/p/msysgit/, pero para los que usamos linux Mint y similares a Ubuntu lo que tienes que hacer es:

sudo apt-get install git git-core git-gui git-doc
(lo que está en negritas es lo esencial, lo demás son agregados y puedes no indicarlos)

luego debes crear la configuración global de git para que se puede rastrear los cambios que tu haces y diferenciarlos con respecto a los demás integrantes del proyecto.

git config --global user.name "Nombres Apellidos"
git config --global user.mail "tunick@gmail.com"


Creacion de un proyecto base con Grails 2.0.3

Vamos a crear un proyecto web base para una aplicación que podría usar un kinder considerando solo poder hacer Altas Bajas y Cambios (ABC) de dos entidades Tutores y Alumnos.  Yo trabajaré en un Linux Mint, las instrucciones en consola son similares en cualquier distribución derivada de Debian o Ubuntu, para windows solo cambiarían las carpetas y las variables de entorno.

Empecemos instalando Grails.

Necesitamos tener instalado java y haber definido nuestra variable de entorno JAVA_HOME.
  1. Descargar grails
  2. Descomprimir ZIP en una carpeta (la mia será /opt )
  3. Crear las variables de entorno GRAILS_HOME y JAVA_HOME (si no existe)
export GRAILS_HOME=/opt/grails-2.0.3
export PATH=$PATH:/opt/grails-2.0.3/bin


Para comprobar que nuestra instalación está completa debemos ejecutar el comando grails para obtener la versión.  En algunos sistemas como el mío se requiere reiniciar la sesión de usuario para que se apliquen los cambios en las variables de entorno.

$ grails -version
Grails version: 2.0.3


Ahora creamos nuestra aplicación, se genera una carpeta con el nombre de la aplicación, ingresamos a dicha carpeta y luego abrimos la consola de grails.

$ grails create-app kinder
| Created Grails Application at /home/wdonet/branches/grails/kinder
$ cd kinder/
$ ls
application.properties  grails-app  lib  scripts  src  test  web-app
$ grails
| Downloading: plugins-list.xml
grails> help

Podemos usar el comando help para ver todos los comandos que tenemos disponibles en la consola de grails, incluso puedes obtener ayuda de un comando en especifico escribiendo por ejemplo : help create-appPero toma nota que la consola de grails es una forma para jugar con el ambiente de tu proyecto, si quieres ejecutar tu aplicación es mejor usar el comando grails (fuera de la consola).

Clases embebidas en Grails

En Grails se pueden mapear clases a entidades simplemente ubicándolas en un paquete dentro de la carpeta /grails-app/domain como se muestra abajo.  Mapeando la clase y atributos a una tabla y columnas con un mismo nombre si no se le especifica otra cosa con la propiedad mapping.

import mx.com.proyecto
class Tutor {
    String nombres
    String paterno
    String materno
    Integer edad
    static constraints = {
        nombres maxSize: 150, nullable: false, blank: false
        paterno maxSize: 80, nullable: false, blank: false
        materno maxSize: 80, nullable: true, blank: false
    }
}

Pero quizá nos interese tener nuestra entidad un poco mas amigable y legible agrupando los tres elementos nombres, paterno y materno dentro de un mismo POJO y seguirla mapeando a las mismas columnas de una sola tabla.

La regla de oro está en definir el POJO en el mismo archivo Tutor.groovy o en un archivo separado pero dentro de la carpeta /src/groovy/ (Nombre.groovy).

Introducción a MongoDB


Me metí un poco a ver como funcionaba CouchDB pero entre revisiones y vistas rápidas a referencias aquí y allá llegue a MongoDB, ambas son alternativas No-SQL (termino que empezó a agarrar fama desde 2009) y que su almacenamiento de datos está orientado a documentos JSON y BSON (Bynary JSON) para ofrecer sistemas flexibles, rápidos, ligeros, potentes y fáciles de usar.

Según Eliot Horowitz, 10gen CTO y co-fundador de mongoDB, prácticamente podrías tomar una base de datos hecha en MySQL, cambias el modelo relacional a uno basado en documentos y obtendrías varias mejoras como:
  1. Documentos embebidos para mejorar la velocidad
    1. El uso de json es más amigables con objetos en lenguajes de programación
    2. El meter documentos embebidos y arreglos reduce la necesidad de hacer joins
  2. Manejabilidad
  3. Desarrollo ágil con base de datos sin esquemas
    1. Al usar JSON/BSON es fácil de codificar y administrar
  4. Escalabilidad horizontal más facil
    1. Es una solución para sistemas que requieren escalar horizontalmente sobre varios servidores.
    2. La funcionalidad de autosharding permite escalar tu cluster agregando mas equipos sin necesidad de dar de baja el servicio.

En realidad no estamos quitando todo el trabajo que ya se ha hecho con las bases de datos relacionales porque en muchas cosas como la creación de indices, llaves primarias, consultas dinámicas y actualizaciones, por mencionar algunas,  se tiene que hacer los mismo, salvo que se busca tener las ventajas arriba descritas.

La gente de apache que desarrolla CouchDB mencionan que los esquemas relacionales funcionarán en algunos casos mientras que los esquemas no-SQL funcionarán en otros.

Introducción a PostgreSQL

Hace un par de días me tuve que meter con PostgreSQL (versión 9.1.3) a manera de conocerlo un poquito ya que no sabía nada y me encontré con algunos detalles.

Para su instalación en Linux Mint o Ubuntu debemos hacer lo siguiente.

  1. sudo apt-get install postgresql libpq-dev (instala el motor y un usuario postgress con todos los privilegios para operar sobre el servidor)
  2. sudo su postgress (esto te permite abrir una sesion con el nuevo usuario postgress)
    1. createuser -d -s -P usuario , creamos un usuario donde:
      • -d es para darle permisos de creación de base de datos
      • -s es para darle permisos de superusuario
      • -P para poderle indicar un password al usuario
    2. exit
  3. sudo apt-get install pgadmin3 - para instalar el cliente gráfico (opcional)

Detalles de interés que se podrán observar en las instrucciones de ejemplo que copio mas adelante:
  • La diferencia contra otros manejadores de Base de Datos es que se puede hacer herencia entre tablas.
  • Cuando se heredan las tablas, las llaves primarias se tienen que redefinir dado que estas no se heredan.
  • Cuando se borran las tablas, los índices también se eliminan de forma automática.
  • Cuando se hacen muchas operaciones de creación/borrado en la base de datos, es necesario darle mantenimiento (opción vacuum en el pgadmin3).
  • La sintaxis para las fechas siempre es: YYYY-MM-DD.

Vamos a los ejemplos ahora sí:
-- Eliminamos la vista
DROP VIEW if exists dime_sus_tutores, dime_personas_sin_cel;

-- Eliminamos indices primero (aunque cuando se borran las tablas estos ya se eliminan)
DROP INDEX if exists idx_clave_escolar;

-- Eliminamos las tablas
drop table if exists
 tutores, personas, alumnos, tutores_alumnos;
 
-- Tabla personas PADRE
create table personas (
 id integer PRIMARY KEY,
 nombres varchar(75) not null,
 genero varchar(1),
 fecha_nacimiento date,
 lugar_nacimiento varchar(150),
 curp varchar(18) unique,
 tel varchar(20),
 cel varchar(20),
 email varchar(50),
 cuando date default current_date
);

-- Tabla hija de personas
create table tutores(
 id integer primary key,
 ocupacion varchar(100)
) inherits (personas);

-- Tutores
insert into tutores (id, nombres, genero, fecha_nacimiento, lugar_nacimiento, cel, ocupacion) values
 (1, 'Ricardo Rogers', 'm', '1970-01-10', 'Ciudad de México', '0445554374879', 'Musico'),
 (2, 'Guillermo Garcia', 'm', '1971-04-12', 'Tlaxcala', '044 55 94637383', 'Contador'),
 (3, 'Pita Perez', 'f', '1964-05-22', 'Ciudad de México', null, 'Ama de casa');

-- Tabla hija de personas
create table alumnos (
 id integer primary key,
 clave_escolar varchar(25),
 fecha_ingreso date,
 carrera varchar(50)
) inherits (personas);

-- Creacion de un indice
create unique index idx_clave_escolar on alumnos(clave_escolar);

insert into alumnos
 (id, nombres, genero, fecha_nacimiento, lugar_nacimiento, cel, clave_escolar, fecha_ingreso, carrera) values
 (4, 'Leonora Rogers Mendoza', 'f', '1994-01-10', 'Ciudad de México', '044 55 12345678', 'a100-101', '2011-08-14', 'informatica'),
 (5, 'Maximiliano Hotel', 'm', '1993-04-12', 'Tlaxcala', '044 55 87654321', 'b200-202', '2011-07-13', 'contaduría'),
 (6, 'Lupita Gómez Pérez', 'f', '1993-02-22', 'Ciudad de México', null, 'c300-303', '2011-06-12', 'contaduría'),
 (7, 'Arturo Gómez Pérez', 'm', '1994-05-22', 'Ciudad de México', null, 'd400-404', '2011-05-11', 'administración')
 ;

-- Tabla que relaciona personas y tutores
create table tutores_alumnos (
 id_tutor integer REFERENCES tutores(id),
 id_alumno integer references alumnos(id),
 primary key (id_tutor, id_alumno)
);

-- relaciones
insert into tutores_alumnos values (1,4),(2,5),(3,6),(3,7);


-- una vista
create view dime_sus_tutores as
 select a.nombres as Alumno, a.clave_escolar as Clave, t.nombres as Tutor, t.cel
 from tutores_alumnos ta
 left join alumnos a on ta.id_alumno = a.id
 right join tutores t on ta.id_tutor = t.id
 order by a.nombres
;

-- otra vista
create view dime_personas_sin_cel as
 select p.id, p.nombres, p.tableoid, c.relname
 from personas p, pg_class c
 where cel is null
 and p.tableoid = c.oid
;


Fuentes:    
  1. @mromtz - Mario Martinez -- Taller de PostgreSQL --
  2. 2 módulos de un curso en línea
  3. Comandos de administracion
  4. www.postgresql.org

Usando una conexión a base de datos distinta en un subreporte de JasperReports

Al incluir un subreporte en JasperReports por default éste utiliza la misma conexión a base de datos que el reporte maestro que contiene el subreporte.


Sin embargo, a veces es deseable que el subreporte se conecte a una base de datos diferente.


Una manera de lograrlo es la siguiente:

  1. Incluir el subreporte como cualquier otro
  2. Agregar un parametro, que en este ejemplo llamaré SUBREPORT_CONNECTION, con Parameter Class = java.sql.Connection , no usar prompt,Default value expression = java.sql.DriverManager.getConnection("jdbc:mysql://localhost:3306/base_de_datos", "usuario", "password")[Obviamente, editar la url para que coincida con el motor de BD usado, nombre de base, puerto, host y demas datos]
  3. En las propiedades del subreporte,Connection type = Use a connection expression,
    Connection expression = $P{SUBREPORT_CONNECTION}(o como sea que se le haya nombrado al parámetro del inciso anterior)
  4. Si al intentar generar el reporte, aparece un error del tipo "No suitable driver found for jdbc:mysql://localhost:3306/base_de_datos", puede funcionar agregar un parametro mas, que se cargue antes del de SUBREPORT_CONNECTION (en iReport se pueden acomodar el orden de los parámetros y ese es el orden de carga también), que no use prompt, que
    Parameter Class = java.lang.Classy con
    Default value expression = Class.forName("com.mysql.jdbc.Driver").getName()[O como sea que se llame la clase Driver del manejador de BD utilizado...]
  5. Por último, si aún con esto surge una excepción ClassNotFoundException para, en este ejemplo, com.mysql.jdbc.Driver, se puede copiar el jar al subdirectorio jre/lib/ext de donde se encuentre instalada la máquina virtual que use JasperReports para compilar los reportes.

Usando una base de datos SQLite en un proyecto de Symfony2

Para configurar una base de datos en un proyecto de Symfony2, se edita el archivo app/config/parameters.ini:


[parameters]
    database_driver   = pdo_sqlite
    database_host     = localhost
    database_port     =
    database_name     = test_project.db
    database_user     = root
    database_password = 


Sin embargo, con esta configuración, que es la default para usar cualquier otro motor de base de datos con Doctrine2 (incluido en cualquier instalación estándar de Symfony2), una base de datos SQLite no funciona.


Lo correcto es, primero, editar y agregar una línea en app/config/config.yml:



doctrine:
    dbal:
        driver:   %database_driver%
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        path:     %database_path%
        charset:  UTF8

Esta línea no se encuentra originalmente en el archivo, se agrega para que Doctrine utilice el parámetro 'database_path', que ahora se agrega a parameters.ini:

[parameters]
    database_driver   = pdo_sqlite
    database_host     = localhost
    database_port     =
    database_name     = test_project.db
    database_user     = 
    database_password = 
    database_path     = /path_to_my_project/app/db/test_project.db

Y con eso, la base de datos queda creada en el path establecido. Notar que para servidores Unix (Linux por ejemplo), este archivo debe quedar con permisos de lectura/escritura por parte del usuario que utilice el servidor web (cualquiera que este sea, http, www-data o lo que sea): Y el directorio donde reside el archivo tambien debe tener permisos de lectura, escritura y ejecución para este mismo usuario (en este caso, el subdirectorio db que yo puse aquí dentro de app/, pero en realidad podría residir donde más nos convenga).


Autowiring basado en anotaciones con Spring Framework

Autowiring se un método que tiene Spring Framework para inyectar de forma automática las dependencias entre clases (servicios, daos, controllers, etc).
Para cada DAO, agrega una anotación de nivel clase @Repository.

Estas anotaciones van en la clase de implementación y no en la intefaz.
import org.sringframework.stereotype.Repository;
@Repository("parametroDao")
public class ParametroDaoImpl implements ParametroDao {
    // ...
}
Para cada componente Servicio, agrega una anotacion de nivel clase @Service.
import org.springframework.stereotype.Service;
@Service("parametroService")
public class ParametroServiceImpl implements ParametroService {
    // ...
}
Para cada controller en Spring MVC, agrega una anotacion de nivel clase @Controller.

No te preocupes de proveer el nombre, no se necesita.
import org.springframework.stereotype.Controller;
@Controller
public class ParametroServiceImpl implements ParametroController {
    // ...
}
Hasta ahora no se ha cambiado nada a la aplicación, se pueden seguir teniendo los nombres de beans usados en la configuración manual, pero es recomendable compilar y construir el proyecto para revisar que no se haya afectado algo.

Una vez hecho lo anterior, hay que decirle a Spring dos cosas: dónde encontrar los nombres para nuestros beans y que estrategia usar para el autowiring.

Para definir donde encontrar los nombres de beans debemos usar el tag <context:component-scan> en el archivo de configuración del contexto de Spring.  Se debe declarar el namespace y schema location:
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd
         http://www.springframework.org/schema/jee
         http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">    
    <context:component-scan base-package="x.y.dao">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>

Las piezas importantes del xml anterior son xmlns:context, xsi_schemaLocation y <context:component-scan>.  Se le está diciendo a Spring que haga un escaneo (búsqueda) de componentes que tengan la aotación @Repository sobre el paquete x.y.dao y si a la anotacion usada se le coloca un valor textual, como en en nuestros casos anteriores del @Repository y el @Service, ése será el nombre a utlilizar como bean para el autowiring

Con la anotacion @Autowired aplicada a los atributos de las clases, se pueden evitar tener setters de dicho atributo, pero si tienes clases unitarias, necesitaríamos setter para inyectar mocks u otras implementaciones.

La convención es utilizar, como nombres de las propiedades que se pretende auto-inyectar, los mismos nombre del componente, lo cual nos permite eliminar los componentes Dao, Service y Controller del archivo de configuracion del contexto de Spring (xml) dado que la configuración ya se está dando en la misma clasa, mediante las anotaciones.

No obstante, sigue siendo recomendable configurar dentro del XML los objetos DataSource (la configuración del orígen de datos, es decir, la Base de Datos), SessionFactory (Hibernate o algún otro ORM) y TransactioManager (Para el control de las transacciones).

Updated: Referencia del entorno de programación en Unix

Resulta que recomendando un libro sobre programación en Unix, me encontré con :

El entorno de programación UNIX (o en amazon)
Kernighan, Brian W.
Pike, Rob
Editorial Pearson

Anteriormente lo vi en mediafire pero ya no esta y yo no lo tengo lamentablemente pero si les es posible comprarlo, se los recomiendo ampliamente.

  • Otra referencia de Fernando Bellas Permuy esta en PDF.

Manual de introducción al comando sed

Se trata de un editor de cadenas, que deriva directamente del comando ed, por lo cual es fácil de aprender, una vez conocido el propio comando ed.  Un editor de cadenas es usado para realizar transformaciones de texto básicas de una cadena de entrada (un archivo o la salida de un pipe). A diferencia de otros editores comunes, sed hace solo una revisión sobre cada entrada, por lo cual es mas eficiente, en especial lo es, cuando filtra texto que pasa por una unión pipe.

Cuando sed filtra un archivo, no altera su contenido, todos los cambios los realiza sobre la salida que imprime. Sed despliega cada renglón automáticamente y por ello p no se necesita después del comando de sustitución (s, por ejemplo s/old/new/). Las comillas son indispensables pues existen metacaracters de sed que tienen significado especial para el shell sobre el cual se ejecuta.

El comando sed tiene una limitación que no se encuentra en ed: no maneja números relativos de renglón. En particular, + y - no son entendidos como expresiones para indicar números de renglón, por lo cual resulta imposible de retroceder a uno o mas renglones anteriores o hacer direccionamientos relativos hacia adelante. Esto se debe a que una vez leído un renglón, el anterior se pierde para siempre; no hay manera de identificar el penúltimo renglón.

En la lista de comandos puede existir cualquiera de los listados más adelante. Cuando se hace uso de uno solo, basta con encerrarlo entre comillas simples como sigue:

sed 's/old/new/' archivo

Pero en el caso de que necesitemos ejecutar varios comandos sobre un mismo archivo, es necesario que estos se encuentren en diferentes lineas, por ejemplo:

sed 's/^/ /
3q' archivo

debugging remoto de scripts Python con winpdb

Usando el programa winpdb se pueden debuggear scripts en Python de manera mas intuitiva que con el clásico pdb.

Una de las ventajas que tiene winpdb es la posibilidad de debuggear scripts que esten ejecutandose en remoto en algun servidor. De esta manera, se pueden debuggear no solo scripts en servidores de producción, por poner un ejemplo, sino también scripts que utilicen curses para manipular la pantalla.

winpdb se basa en una arquitectura de cliente-servidor que comunica al servidor (el cual ejecuta el script a debuggear en sí) a través de sockets con el cliente (el cual ejecuta la interfaz del debugger).

Configurar POI en Spring 3 para generar archivos Excel

He decidido registrar el proceso de como generar archivos Excel con POI mediante Spring 3 para que no se me olvide (aunque es bastante sencillo).  Me sorprendí de terminarlo en tan sólo 3 pasos!

1) Generar un controller que obtiene los valores que se pretenden mostrar en la vista, los agrega al modelmap de MVC que maneja Spring y luego devuelva el nombre de la vista encargada de generar el excel.

@Controller
@RequestMapping("/excel")
public class ExcelController {

    @Autowired
    private Servicio servicio;

    @RequestMapping(value = "/{parametro}", method = RequestMethod.GET)
    public String generarExcelByParametro(
            ModelMap modelMap, HttpServletResponse response,
            @PathVariable("parametro") String nombreVista) {
        modelMap.put("datos", servicio.obtenerDatos(parametro));

        response.setHeader("Content-type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition","attachment; filename=\"excel.xls\"");
        return "reporteExcel";
    }

}

Observa que el método generarExcelByParametro() del controller responde a una petición http://{servidor:puerto}/{contexto}/excel/{parametro} y realiza algo en un servicio que devuelve cierta información que se espera administrar de lado de la vista (más adelante lo vemos) y lo guarda dentro del ModelMap de spring con el identificador "datos".

Los headers que se agregan al response, son solo para asegurar que cuando se genere el archivo .xls, se identifique como tal y se obligue al usuario a descargarlo.

Finalmente la cadena ("reporteExcel") que se devuelve determina el nombre de la vista que interpretara los datos para generar el documento.

Servidor VNC para sesiones de escritorios remotos

Introducción
VNC (Virtual Network Computer) es el software a través del cual se puede iniciar sesión en escritorio remoto con GNU/Linux.

Otra opción es el RDP de Windows, sin embargo aquí explicaremos únicamente como configurar el servidor para el caso de VNC.

Lo primero que hay que saber es que VNC funciona para controlar escritorios remotos que utilizan el servidor gráfico X-Window , el default de GNU/Linux hasta ahora. Sin entrar en detalles de cómo funciona X-Window, basta saber que en este tutorial explicaremos dos opciones:

  1. controlar el escritorio X real que se tenga en el escritorio remoto
  2. controlar un escritorio X virtual que se crea a demanda en dicho escritorio remoto
Ambas opciones tienen posibilidades de aplicación.