Fetishcode
RoadMap de nuevos lanzamientos de JDeveloper
Octubre 21st, 2011 - [Enlace local]
A
» Leer más, comentarios, etc...
Picando Código
Android Beam – ¿el futuro es NFC?
Octubre 21st, 2011 - [Enlace local]
Recientemente Google mostró la nueva versión de Android: Ice Cream Sandwich. Desde el punto de vista del usuario, evolucionó la interfaz gráfica y usabilidad, cambios en el comportamiento, accesibilidad y otros. Pueden ver un análisis más completo de lo nuevo en Ice Cream Sandwich en El Android Libre.
Desde el punto de vista de los desarrolladores, Android 4.0 unifica los elementos de la API 3.x enfocada a tablets en un solo framework de interfaz gráfica para teléfonos, tables y más. Hay varias mejoras desde la cámara, control por audio, efectos, widgets y demás.
Pero hubo una característica en especial de Android 4.0 que me generó el efecto “mi cerebro explotó” al verlo. No tanto por la demo que se hizo en sí de la nueva funcionalidad, sino por el potencial que imagino en este protocolo: Android Beam.
Como dice en el sitio de Android Developers: Android Beam es una característica basada en NFC que permite a los usuarios compartir información sobre las aplicaciones que están usando instantáneamente, solo tocando dos teléfonos con NFC habilitado. Cuando los dispositivos están dentro de rango – a unos pocos centímetros de distancia – el sistema levanta una conexión NFC y muestra una interfaz gráfica compartida. Para compartir lo que sea que estén viendo con el otro dispositivo, los usuarios solo deben tocar la pantalla.
La tecnología NFC – Near field communication (comunicación de campo cercano) no es nueva, pero la descubrí a partir de lo nuevo de Android. Fue co inventada en 2002 por Sony y NXP Semiconductors. En 2004 se formó el NFC Forum que promueve compartir y realizar transacciones entre dispositivos NFC y desarrolla certificados de conformidad con el estándard NFC.
Por lo que podemos leer en Wikipedia, se espera que su uso aumente al permitir realizar pagos a través de un smartphone. Los teléfonos pueden almacenar la información de una tarjeta de crédito y con solo tocar un lector con su teléfono, podrían realizar un pago instantáneamente.
Algunos de los usos para esta tecnología pueden ser como documento de identidad, obtener datos de terminales en museos o tiendas, compartir contactos, archivos y demás. En el campo de las redes sociales puede ser usado para compartir, pagar, jugar o agregar a otra persona como contacto, entre otras cosas. Ni que hablar de las posibilidades en cuanto a comercio electrónico y al ser de rango corto, mantener la información de un documento de identidad privada.
Y siguiendo con el sitio de desarrolladores de Android, Android Beam es una nueva forma de disparar la interacción basada en proximidad de cualquier tipo. Esta versión ofrece soporte a bajo nivel para NFC y compartir una interfaz gráfica. Los desarrolladores tendremos un control total de la información que se comparte y cómo se maneja, por lo que el tipo de interacción está limitado por el alcance de las ideas.
En comparación con Bluetooth, tiene la ventaja de establecer la conexión automáticamente en menos de una décima de segundo. Mediante Bluetooth debemos configurar manualmente identificando los dispositivos lo que lleva un tiempo mayor. Sin embargo, la velocidad de transferencia de NFC es de 424 kbit/s mientras que Bluetooth 2.2 permite una velocidad de hasta 2.1 Mbit/s. Al ser de rango más corto, NFC se adecúa mejor en areas con mucha gente y señales que transmitan interferencia. Mediante Android Beam, se puede iniciar una conexión para transferir datos por Bluetooth de manera más simple.
A continuación un video que muestra de manera bastante simple cómo funciona Android Beam con dos Samsung Galaxy Nexus:
Ya hay varios dispositivos Nokia, Samsung, Motorola y Blackberry que incluyen la tecnología NFC. Apple estaría desarrollando un sistema de pagos móviles con NFC, por lo que nuevas generaciones de productos iPhone, iPod y iPad estarían equipados con esta capacidad. Además, Google anunció en mayo pasado Google Wallet, una aplicación para Android que hará uso de NFC para realizar pagos en tiendas guardando la información de la tarjeta de crédito en la aplicación. Con tantas empresas apostando a esta tecnología, parece ser el futuro estándar en lo que se refiere a pagos electrónicos. Es sí, seguramente también traiga sus problemas de seguridad, ya que perder el teléfono móvil va a implicar un riesgo cada vez mayor.
Si bien se ve que su crecimiento va a ser definido por el éxito que tengan los sistemas de pago, al ver los videos imaginé algo más relacionado a lo que se viene viendo como la transformación de los teléfonos móviles en nuestra computadora personal. Imaginen que un día tal vez la única computadora que tengamos sea nuestro “teléfono”. Nuestras estaciones de trabajo, centros de entretenimiento y demás serán únicamente dispositivos de salida para un único “teléfono”. Al llegar al trabajo, con solo tocar un LED de 19 pulgadas con un receptor NFC, el teléfono se conectaría y pasaría a ser nuestra interfaz visual, junto a un teclado y mouse. Ya en casa, con solo tocar la televisión accederíamos a todo el contenido multimedia usando ese único dispositivo.
A esto agregarle la transferencia de energía inalámbrica para cargar la batería del dispositivo, y viviríamos en un mundo sin cables. Mi imaginación empezó a volar tras ver lo que es NFC, ya que nunca confié mucho en la tecnología Wifi. Por alguna razón todavía me da la impresión de ser algo inestable y lento. Digamos que NFC me mostró una conexión instantánea sin configuración, lo que me hizo imaginar la casa del mañana sin cables y controlar todo desde un solo dispositivo sin cables.
Veremos cómo se desarrolla esto en el futuro…
Comparte:
» Leer más, comentarios, etc...
Javier Pérez
Google Reader: el compartir se va a acabar
Octubre 21st, 2011 - [Enlace local]

Google Reader, un producto de excelentísima calidad para los pocos que lo usamos, y un producto completamente desconocido para el resto de mortales, esta muy cerca de sufrir cambios muy importantes.
El más obvio y quizás irrelevante es el cambio de diseño, para adaptarse a la nueva línea que está imponiendo Google a sus productos tras el lanzamiento de Google+. Otro cambio obvio es la integración de Google Reader con Google+, permitiendo compartir enlaces directamente en la nueva red social de Google.
Y el más relevante, y por lo que estamos muy preocupados sus agradecidísimos usuarios, es la eliminación de la capa social de Google Reader. Es decir, ya no podremos seguir los feeds de otros usuarios, ni compartir feeds con los que nos siguen, una herramienta muy útil para todos aquellos que usamos este producto para mantenernos informados de todo lo que se cuece y deja de cocer en el mundo.
¿Eres usuario de Google Reader? ¿Qué te parece este último cambio?
Hablan sobre esto Enrique Dans y Antonio Ortiz.
» Leer más, comentarios, etc...
Javier Pérez
Agur ETA
Octubre 21st, 2011 - [Enlace local]

La banda terrorista ETA anuncia, al fin, el cese de su lucha armada. El 20 de octubre de 2011 se recordará como un nuevo hito en la historia de nuestra democracia.
Pero los demócratas aún esperamos nuevos hitos para nuestra joven democracia:
- Separación total de los poderes públicos.
- Democracia participativa y representativa real. Fin del bipartidismo.
- Soberanía del pueblo (y no de los mercados).
- Educación y empleo, fundamentales para un voto responsable y libre.
- Cumplimiento de la constitución por parte de los poderes públicos (por ejemplo, vivienda digna, nacionalización de empresas por el bien común, etc.).
» Leer más, comentarios, etc...
Javier Pérez
Google+ añadirá soporte a Google Apps y aceptará pseudónimos
Octubre 20th, 2011 - [Enlace local]
Google+ pretende ser el producto estrella de Google, y sus movimientos parecen encaminados a ese objetivo, aunque las novedades y mejoras vienen con cuenta gotas.
La noticia de que permitirán cuentas Google Apps en Google+ era muy esperada. Somos muchos los que usamos los productos de Google a través de Google Apps y estamos ansiosos por poder usar también Google+ con dichas cuentas.
Que Google+ acepte usar pseudónimos y que no obligue a publicar el nombre real parece más bien un movimiento de someterse a la demanda, lo cual me parece una pequeña derrota de Google+. Yo, personalmente, prefiero una red social donde sus usuarios aparezcan con nombre y apellidos, algo más personal y más cercano al mundo real. Pero desgraciadamente el fanático del anonimato en Internet (falso anonimato) le ha ganado esta batalla a Google.
Ansiamos también poder crear páginas en Google+, de forma similar a las páginas de Facebook. Y una API con la que poder publicar y no sólo leer contenido público es también muy esperada por toda la enorme comunidad con la que ya cuenta Google+.

» Leer más, comentarios, etc...
Preparando SCJP
El recolector de basura
Octubre 20th, 2011 - [Enlace local]
Muchos lenguajes de programación permiten asignar memoria dinámica en tiempo de ejecución pero es el programador el que tiene la responsabilidad de liberarla.
Sin embargo, Java proporciona un hilo en el nivel del sistema que administra esta memoria, busca la que está en desuso y la libera. Es el recolector de basura o Garbage Collector (GC).
Cuándo se ejecuta:
El GC está bajo el control de la JVM y ella decide cuándo ejecutarlo. Dentro de un programa se puede solicitar la ejecución pero no hay ninguna garantía de que se ejecute.
Cómo funciona:
Los modelos de reciclaje de la memoria pueden variar considerablemente en cada implementación de la JVM. Lo que debemos tener claro es cuándo un objeto es elegible por el GC.
Un objeto es elegible cuando ningún thread vivo puede acceder a él.
Cómo hacer un objeto elegible:
- Estableciendo la referencia a null:
Cuando asignamos la referencia de un objeto a null estamos perdiendo cualquier posibilidad de acceder a él.public class aNull{ public static void main (String[] args){ Integer a = new Integer(10); //1 a = null; //2 //ahora el objeto Integer(10) es elegible por el GC. } }//1 Creación del objeto.
//2 La referencia ya no apunta al objeto. La referencia es igual a null. El objeto es ahora elegible por el GC.
- Reasignando la referencia:
Cuando hacemos que la referencia que apunta a un objeto apunte a otro distinto dejando el primero inaccesible.public class Reasigno{ public static void main (String[] args){ Integer a = new Integer(10); //1 Integer b = new Integer(20); //2 a = b; //3 //ahora el objeto Integer(10) es elegible por el GC. } }//1 y //2 Creación de los objetos.
//3 La referencia a y b están ahora apuntando al segundo objeto, siendo el primero elegible para el GC.
- Cuando la referencia está aíslada:
Se produce cuando un objeto tiene como miembros otros objetos de su misma clase y aunque se pierdan las referencias de estos objetos aún conservan entre ellos referencias vivas que son elegibles para el GC.public class Aislada{ Aislada vecina; public static void main (String[] args){ Aislada a = new Aislada(); //1 Aislada b = new Aislada(); a.vecina = b; //2 b.vecina = c; a = null; //3 b = null; // Aunque las pongamos a null entre los objetos tienen referencias. } }//1 y //2: Creación de los objetos Aislada y asignación de la vecina.
//3: Se ponen las referencias a null. Los dos objetos Aisladas son elegibles para el GC.
Solicitar la ejecución del GC:
Como hemos dicho antes no se puede forzar la ejecución del recolector de basuras. Se solicita su ejecución mediante la siguiente instrucción pero no se nos garantiza que se ejecute.
Se puede ejecutar mediante:
System.gc();
U obteniendo una instancia de Runtime:
Runtime rt = Runtime.getRuntime();
rt.gc();
Método finalize():
Este método está definido en la clase Object y por tanto todos los objetos lo heredan. En él
podemos escribir cualquier código que queramos que se ejecute antes de que el GC borre el objeto.
Como la ejecución del GC no está garantizada que se ejecute la ejecución de finalize() tampoco está garantizada.
Cada objeto sólo podrá llamar a este método una vez. En este código se podría hacer inelegible el objeto, por ejemplo, volviendo a asignarle una referencia.
Filed under: Estudio, Tema 3 Tagged: Certificacion Java, Garbage Collector, GC, Java, ocpjp, Programacion, SCJP, Tecnologia
» Leer más, comentarios, etc...
Variable not found
[Auges] Seguridad de aplicaciones Web. Las técnicas más interesantes para que no hackeen tu aplicación
Octubre 20th, 2011 - [Enlace local]
Id apuntando en la agenda, si no lo habéis hecho ya, que el próximo martes 25 de Octubre a las 19:00 (horario peninsular español) tenemos en Auges un interesantísimo evento que, si sois desarrolladores web, no os podéis perder.
Para empezar, tendremos aquí a José Manuel Alarcón, del que poco se puede decir que no conozcáis ya: Ingeniero industrial, Microsoft MVP desde el año 2004, Director de Krasis, autor de cientos de artículos, varios libros, ponente en decenas de conferencias y charlas … vaya, uno de los grandes :-)
Y el tema elegido es de vital importancia para todos los que trabajamos en la web: la seguridad.
Programar es mucho más que la simple creación de aplicaciones que cumplen con la funcionalidad para la que fueron diseñadas. Existen otras muchas consideraciones que hacer y multitud de características tan importantes como la propia funcionalidad que se deben tener en cuenta: rendimiento, extensibilidad, facilidad de mantenimiento, etc... entre las que destaca especialmente la seguridad del código que se escribePor supuesto, podéis asistir desde casa o el trabajo (es un Webcast online), y la asistencia al evento es totalmente gratuita. Para acceder, simplemente debéis registraros en la siguiente dirección:
De poco o de nada sirve una aplicación que lleva a cabo su cometido principal pero que permite que casi cualquiera pueda acceder a la información que supuestamente protege o que, debido a la escritura de código descuidado, un competidor desleal impide su funcionamiento cuando más se necesita.
Y no, no llega con tener un buen cortafuegos si el fallo está en la lógica de la aplicación.
En esta charla se analizarán los principales puntos flojos de seguridad que suele haber en las aplicaciones Web ASP.NET, y se enseñará cómo evitarlos. Entre otros temas se tratarán la correcta configuración de IIS, la autenticación y autorización hechas correctamente, la suplantación de usuarios del sistema, las inyecciones de SQL, las secuencias de comandos entre sitios (XSS), los problemas de canonicalización, los ataques Cross Site Request Forgery (CSRF)...
https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032497158&Culture=es-ES
Publicado en: Variable not found.
» Leer más, comentarios, etc...
Viricmind Labs
Primeros pasos con Node.js
Octubre 19th, 2011 - [Enlace local]
Estos días estaré experimentando con Nodejs y aprocecharé para escribir un poco sobre mi aprendizaje en el blog. Nodejs es primo-hermano de herramientas como Twisted o Tornado, pero escrito mayoritariamente en Javascript y no en Python, y que aprovecha toda la potencia de la máquina virtual V8 que adquirió Google para su navegador Chrome, que no es moco de pavo
. Empecemos pues!
Instalación de Nodejs
En todo momento presupongo que estamos trabajando sobre Linux y que tenemos instaladas ciertas herramientas básicas de desarrollo: compiladores, make, python, y la biblioteca libssl-dev. En caso de que nos falte algo no creo que suponga ningún impedimento, normalmente el sistema nos indicará qué nos falta y la instalación por lo general se podrá hacer a través de los gestores de paquetes más usados: apt-get, aptitude, yum y alguno que otro más.
En primer lugar descargaremos el paquete de código fuente estable (a día de hoy es la versión 0.4.12, del día 15 de Septiembre de 2011), lo descomprimimos y entramos desde la línea de comandos en el nuevo directorio creado tras la descompresión. Allí debemos ejecutar los siguientes comandos:
1 2 3 | ./configure make sudo make install |
¿Ya está? No, casi... Nos falta NPM, el gestor de paquetes de Nodejs que nos facilitará la vida (aunque no es imprescindible por el momento).
Instalación de NPM
Para instalar NPM nos "arriesgaremos" a usar la versión disponible en su repositorio Git oficial... y es que no hay ninguna versión "estable" por el momento. Así que, evidentemente, tendremos que tener instalado git en nuestro sistema.
Lo primero que tenemos que hacer es teclear lo siguiente en la línea de comandos:
1 | git clone git://github.com/isaacs/npm.git |
Seguidamente debemos entrar en el nuevo directorio creado y ejecutar la siguiente orden:
1 | sudo make install |
Como podemos ver el proceso no tiene nada de complicado
, puede que fuera preferible usar los acostumbrados gestores de paquetes... pero la comodidad que nos aportan tendría que pagarse con una falta importante de actualización, y más teniendo en cuenta el temprano estado de desarrollo de estas piezas de software y la cantidad de cambios que se suceden constantemente en ellas.
Bien, pasemos a la acción, vayamos a crear nuestra primera aplicación basada en Nodejs! El código es bastante simple y se entiende perfectamente, aunque en cierto modo puede asustar un poco porque un simple "Hello World!" es algo más complicadillo que si lo hiciéramos directamente en PHP. Podemos llamar al fichero ejemplo.js .
1 2 3 4 5 6 7 8 | var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337, "127.0.0.1"); console.log('Server running at http://127.0.0.1:1337/'); |
Como podemos observar el código debe tener en cuenta incluso las cabeceras HTTP, pero no hay que preocuparse, en artículos posteriores veremos como gracias a un gran conjunto de librerías y microframeworks el trabajo con Nodejs puede llegar a ser incluso divertido (y nos serviremos de NPM para cargar esas librerías de forma sencilla). Por cierto, para ver el resultado en el navegador deberéis visitar la dirección http://127.0.0.1:1337/ tal y como indica el propio ejemplo a través de la línea de comandos.
Como segundo avance de lo que veremos en los próximos artículos, entre otras cosas revisitaremos el primer ejemplo mencionado, pero esta vez escrito en Coffeescript, un lenguaje similar a Python (y por lo tanto mucho más agradable que Javascript) que generalmente se compila a Javascript.
» Leer más, comentarios, etc...
Monocaffe
Java’s Ghost JVMs
Octubre 19th, 2011 - [Enlace local]
It's a nice day when you end up digging through some of the JDK source code to find out what is broken with one of the JDK tools like JPS or JConsole. Today was one of those days.
The problem was with our JBoss monitoring tool which depends on jconsoles LocalVirtualMachine.getAllVirtualMachines() method. For some reason, after a controlled restart of the farm, a couple of servers were being reported as offline. Looking at the log files, I was able to see that the PID for this servers was wrong and the process couldn't connect to retrieve the data (this is done using JMX).
The solution was to see what this method was doing with the source code from LocalVmManager.java and PerfDataFile.java
So how does tools like JPS, JConsole or VisualVM know the JVMs running in a system? They simply look in the folder /tmp/hsperfdata_foo where a 32KB data file with the PID as name is created for each JVM.
Back to our problem. After the restart, some of the files that should have been removed when the JVM was killed were still there, so this was giving the monitoring process a wrong PID and it couldn't connect to the JVM and do its magic.
Solution: remove the unused files and everything works as expected.
So, the next time you need to know all the JVM running on your system, remember this: $ls /tmp/hsperfdata_*/
» Leer más, comentarios, etc...
Ingenieria de Software / Software Engineering / Project Management / Business Process Management
Microsoft Project 2010 SCRUM Solution Starter
Octubre 19th, 2011 - [Enlace local]
Muy buen addon para Project 2010, SCRUM Solution starter nos permite usar los componentes de SCRUM como Product Backlog, Sprint Backlog y Burndown y Sprint Burndown Graph, de las limitantes fuertes es que no esta diseñado para Project Server 2010, a continuación la página de este addon
http://archive.msdn.microsoft.com/P2010Scrum
» Leer más, comentarios, etc...
Ingenieria de Software / Software Engineering / Project Management / Business Process Management
A Solid Project Team
Octubre 18th, 2011 - [Enlace local]
Que características debiera tener un equipo de trabajo???, es algo que obviamente todo Project Manager debiera saber pero desgraciadamente no es así, el siguiente artículo menciona algunas muy importantes
» Leer más, comentarios, etc...
Picando Código
1er. Concurso de Historietas de la Asociación Uruguaya de Creadores de Historietas (AUCH)
Octubre 18th, 2011 - [Enlace local]
Hago eco de una noticia publicada en Multiverseros. La flamante AUCH, Asociación Uruguaya de Creadores de Historietas presenta su primer concurso.
Del sitio web de AUCH:
Las obras ganadoras formarán parte de un álbum a presentarse como proyecto en el Fondo Concursable para la Cultura 2012 del Ministerio de Educación y Cultura en la categoría Relato Gráfico.
El Concurso tendrá la presencia del mismísimo Enrique Alcatena, quién junto a Esteban Caballero, evaluarán todas las historietas presentadas. Para descargar las bases del Concurso hacer click aquí.
Las historietas deben desarrollar el tema “Verano”, deben contar con al menos un miembro de AUCH en el equipo, y hay plazo hasta el 31 de enero de 2012.
Comparte:
» Leer más, comentarios, etc...
Koalite's blog
Cuando Google Docs no te deja escribir
Octubre 18th, 2011 - [Enlace local]
De vez en cuando tengo un problema bastante molesto. Uso Google Docs para casi todo y, cuando intento hacerlo desde Ubuntu 11.04 con Firefox 5+, a veces no puedo escribir.
Puedo crear un documento, veo el cursor parpadeando, pero si intento escribir… nada. Si intento pegar algo, nada. Sin embargo, todo lo demás parece funcionar: puedo seleccionar opciones en los menús, cambiar el nombre del documento, etc.
La “solución” que he encontrado es cambiar el foco a la barra de direcciones (o a cualquier otro cuadro de texto de firefox) y escribir cualquier cosa. Después de eso, ya puedo volver a mandar el foco al documento de Google Docs y escribir sin problemas.
» Leer más, comentarios, etc...
Variable not found
Compactación y minimización de Javascript y CSS para ASP.NET
Octubre 18th, 2011 - [Enlace local]
Había comentado que una de las novedades que ya podíamos disfrutar en la developer preview de MVC 4 era el sistema de compactación y minimización de scripts y CSS, y que, además de ser bastante útil y sencillo, podíamos utilizarlo a día de hoy en nuestras aplicaciones MVC 3 e incluso en ASP.NET Webforms.
Este mecanismo hace posible la creación de bundles, o paquetes de uno o varios archivos de scripts o estilos, que son optimizados en tamaño por el servidor y cargados desde las páginas en una única petición. El proceso de compactación se realizaría en servidor, pero sólo la primera vez, quedando almacenado en caché para las peticiones posteriores.
Por ejemplo, en el caso de los scripts, en lugar de tener en nuestras vistas o layouts referencias hacia decenas de archivos “.js” (jQuery, UI, validadores, plugins, etc.), simplemente incluiríamos la carga de un archivo, que sería generado por el servidor mediante el empaquetado y la compactación de todos ellos.
Y con las hojas de estilo CSS ocurriría lo mismo: podríamos cargar desde el cliente un único archivo .css, que contendría la suma compactada de todos los necesarios para el funcionamiento de la aplicación.
<disclaimer>Para empezar, el paquete
Todo lo que voy a contar a continuación está probado con la versión previa para desarrolladores de MVC. El ensamblado Microsoft.Web.Optimization es la versión 0.1, y de él puede cambiar hasta el nombre ;-)</disclaimer>
Microsoft.Web.Optimization se incluye instalado de serie en MVC 4 (a día de hoy, hay que decir). En cambio, en ASP.NET MVC 3 o Webforms debemos descargarlo utilizando Nuget:PM> Install-Package Microsoft.Web.Optimization
Successfully installed 'Microsoft.Web.Optimization 0.1'.
Successfully added 'Microsoft.Web.Optimization 0.1' to Mvc4Application49.
Una vez instalado, ya casi tenemos el trabajo hecho ;-)La forma rápida
Si lo que queremos es probar rápidamente el sistema de empaquetado, basta con añadir el siguiente código en la inicialización de nuestra aplicación: protected void Application_Start()
{
...
BundleTable.Bundles.EnableDefaultBundles();
...
¡Y esto es todo! A partir de este momento, podemos acceder a las URL:- /scripts/js, que nos retornará un único archivo script conteniendo todos los scripts disponibles en la carpeta
/scriptsdel proyecto (sin incluir subdirectorios), minimizados y compactados. - /content/css, que de la misma forma, retornará un único archivo .css conteniendo la suma compactada de todos los css que el sistema encuentre en la carpeta
/content.
- Cualquier petición del estilo “
{path}/js” hará que el sistema retorne en un único archivo compactado todos los scripts disponibles en la carpeta{path}. - De la misma forma, todas las peticiones a “
{path}/css” retornará un único archivo .css con la suma compactada de todas las hojas de estilo presentes en la carpeta{path}. - Se eliminan las versiones de documentación (*-vsdoc.js, *.debug.js…), es decir, serán ignoradas todas ellas a la hora de generar el archivo compactado único.
- Se tiene en cuenta la ordenación, sobre todo a la hora de anexar los scripts en un único archivo. De esta forma, scripts como jQuery se carguen antes que sus plugins, y otros habituales en el mundo CSS como reset.css o normalize.css sean cargados al final del bundle de estilos.
<link href="/Content/css" rel="stylesheet" type="text/css" /> <script src="/Scripts/js" type="text/javascript"></script>Ojo, muy Importante: para que todo funcione bien los scripts deben ser sintácticamente correctos, de lo contrario podemos encontrarnos con que la versión compactada nos dé fallos en tiempo de ejecución. Esto es así porque el proceso de compactación no sólo elimina espacios sobrantes, sino que acorta los nombres de variables y funciones privadas.
De hecho, a día de hoy este sistema no funciona bien con las bibliotecas que se encuentran por defecto en la carpeta
/scripts de los proyectos MVC 3, es necesario actualizarlos (usando Nuget son sólo unos segundos). Con los scripts incluidos en MVC 4 no hay problema. También los .css deben ser correctos, aunque en caso contrario lo único que ocurrirá es que se retornará un único archivo sin compactar.
¡Quiero más control!
El sistema de bundling es realmente potente y flexible. En el ejemplo anterior se trataba de poner en marcha este sistema de forma rápida, pero se puede conseguir un control mucho más exhaustivo sobre lo que se compacta y lo que no, y sobre la forma de acceder a estos recursos.La siguiente porción de código muestra cómo podríamos inicializar la tabla de bundles de forma más detallada:
Bundle cssBundle = new Bundle("~/estilo.css", typeof(CssMinify));
cssBundle.AddDirectory("/content", "*.css", searchSubdirectories: true);
BundleTable.Bundles.Add(cssBundle);
Bundle jsBundle = new Bundle("~/scripts.js", typeof (JsMinify));
jsBundle.AddFile("~/scripts/jquery-1.6.4.js");
jsBundle.AddFile("~/scripts/modernizr-2.0.6.js");
jsBundle.AddDirectory("~/scripts/site", "*.js", searchSubdirectories: false);
BundleTable.Bundles.Add(jsBundle);
Como podemos observar, en primer lugar se crea un bundle de tipo CSS, en el que se añaden todos los archivos con el patrón *.css que se encuentren en la carpeta /content y todos sus subdirectorios. Este paquete compactado sería accesible a través de la URL “/estilo.css”.En el segundo bloque creamos un bundle en la URL
“/script.js” al que añadimos algunos archivos de forma manual, y todos los .js que encontremos en la carpeta /scripts/site, sin incluir subdirectorios.¿Fácil, verdad?
En conclusión, aunque todavía tendrá que cambiar, en este momento ya podemos ver una herramienta muy potente y sencilla de utilizar, que seguro entrará a formar parte de nuestros desarrollos en breve. Ya el colmo sería que los contenidos se comprimieran en gzip, pero por la pinta que tienen los componentes probablemente sea una funcionalidad a la que podamos aspirar en breve :-)
Publicado en: Variable not found.
» Leer más, comentarios, etc...
Arragonán
I’m speaking at Greach
Octubre 17th, 2011 - [Enlace local]
El día 4 de Noviembre, se celebra en Madrid (Universidad San Pablo CEU) la conferencia española de Groovy: Greach.
Pues resulta que andaré por ahí para hablar de optimización de webs Grails, sobre buenas prácticas de desarrollo web y como llevarlas a cabo en proyectos Grails.
Cuando desarrollamos una web podemos seguir algunas buenas prácticas para que estas resulten más rápidas, lo que que repercute en una mejora en la experiencia de usuario, escalabilidad o incluso en el posicionamiento en buscadores.
En esta charla se tratarán esas buenas prácticas, como podemos llevarlas a cabo con Grails y el uso de algunos plugins que nos facilitan el trabajo.
Esta pedazo de agenda es principalmente gracias a Alberto Vilches, que es el que se lo ha estado y está currando.
* La idea del video viene por los “hola conferencia rails”
» Leer más, comentarios, etc...
Javier Pérez
Series de TV que me entusiasman: Breaking Bad
Octubre 17th, 2011 - [Enlace local]
La anterior serie de la que hablé fue The Big C, una bellísima historia sobre el difícil viaje a la felicidad, que acaba de terminar su segunda temporada.
Ahora hablo de otra serie que me entusiasma, posiblemente de las 5 mejores series de todos los tiempos, para mí: Breaking Bad. También acaba de terminar su temporada, la cuarta, y ya estoy ansioso por ver la siguiente. Es una de esas series que cada capítulo te sorprende más y más, y que te deja con unas ganas locas de ver el siguiente.
La serie la emite la AMC (The Killing, The Walking Dead), y ha sido creada y producida por Vince Gilligan (un genio). Ha ganado seis de los 16 premios Emmy a los que ha sido nominada. En España la emite la Paramount Comedy (acaba de empezar a emitir la última temporada). Y es fundamental que se disfrute en versión original.
Argumento
Bryan Cranston, el famoso padre de Malcolm in the Middle (irreconocible en esta serie), y con papeles en Salvar al soldado Ryan o Pequeña Miss Sunshine, es el principal protagonista, Walter White, un profesor de química de instituto muy correcto, marido de la espectacular Skyler White (Anna Gunn) y padre de Walter White Jr. (RJ Mitte), un chaval que sufre de una leve parálisis cerebral (también en la vida real).
La serie comienza cuando al bueno de Walter White le diagnostican un tumor cerebral. A partir de entonces se plantea que va a dejar a su familia sin nada, y sin poder costear el tratamiento que necesita su hijo. Por azar se reencuentra con un antiguo alumno, Jesse Pinkman (Aaron Paul: Misión Imposible III, K-Pax, y algunas apariciones en otras series de TV), con quien se adentra en el peligroso y lucrativo negocio de la producción de drogas sintéticas.
Lo que comenzó siendo un trabajo temporal para conseguir dinero para su familia tras su muerte, finalmente se convierte en un nuevo y sorprendente mundo del que Walter White no quiere desprenderse.
Por qué me entusiasma
El guión, la interpretación, la fotografía… todo luce a un nivel más que brillante, y eso ya es motivo más que suficiente. Pero además está la historia de fondo… Un profesor aburrido con su vida de buena persona y marido correcto, lo que algunos llamarían un muermo, decide que ya es hora de tomar las riendas, de ser quien él es realmente, que ya es hora de dejar de interpretar un papel, y de vivir su propia vida. Es una historia que todos podríamos haber vivido alguna vez (a excepción de lo de convertirse en productor de droga, espero), y por lo tanto con la que podemos sentirnos identificados desde el primer momento.
Trata de la amistad, de la confianza, del matrimonio, de la sinceridad, del egoísmo… todo aderezado con un poquito de acción y humor. Simplemente imprescindible.

Descargar Breaking Bad
- Breaking Bad: temporada 1
- Breaking Bad: temporada 2
- Breaking Bad: temporada 3
- Breaking Bad: temporada 4
» Leer más, comentarios, etc...
Javier Pérez
Cómo promocionar un blog: Introducción
Octubre 17th, 2011 - [Enlace local]

Hace dos años publiqué 30 ideas para promocionar tu blog, donde expliqué los diversos métodos más sencillos que por esas fechas se podían poner en práctica para hacer llegar tu blog a mucha más gente. Pero dos años son demasiados en este mundillo, y mucho ha cambiado la forma de promocionar un blog, o una web en general, desde entonces. Así que tómense estos artículos como una revisión, actualización y ampliación de aquel primer artículo. En esta serie de artículos explicaré conceptos muy básicos de marketing online aplicados a la promoción de un blog.
Si lo que quieres es saber cómo crear contenidos de calidad que interesen a muchísima gente quizás tengas que esperar a otro artículo. Aquí damos por sentado que escribes artículos de calidad, porque de otro modo de nada servirá que hagas esfuerzos en difundir tu blog.
Cada nuevo artículo de esta serie (semanal) se dedicará a un área concreto del marketing online, aplicado siempre a la promoción de un blog, aunque también son aplicables a cualquier tipo de web.
Índice
- SEO
- SEM
- Social Media
- Emailing
- Usabilidad
- Analítica Web
- Afiliación
Tecnología
La tecnología que uses es fundamental para poder aplicar las campañas de marketing que necesites. La elección de una plataforma de blogging es por tanto muy crítica. Existen muchas y gratuitas, pero te aconsejo que te decantes por WordPress, que es en la que nos vamos a centrar en todos estos artículos. WordPress es muy fácil de usar, y sobre todo tiene todos los plugins que puedas necesitar para realizar tus campañas de marketing. Blogger es una plataforma que ha mejorado mucho en estos últimos tiempos, y mucho más que parece que va a mejorar, pero al menos de momento no alcanza el poder de WordPress. Aún así se merece que no la perdamos de vista como una opción de futuro. Para usar WordPress tienes dos opciones:
- Contratar un hosting e instalar allí WordPress. La opción recomendada.
- Crearte una cuenta directamente en wordpress.com, donde tendrás un wordpress listo para ser usado.
Con la primera opción tendrás más libertad para hacer lo que quieras, pero si no tienes conocimientos técnicos quizás te lleve más tiempo dejarlo perfectamente configurado. La segunda opción te limita bastante pero a cambio puedes ponerte a trabajar de inmediato (además, es gratuito).
Y no te olvides de comprar un dominio. Un blog cuya URL sea miblogchupiguay.blogspot.com puede ser el mejor blog del mundo, pero siempre parecerá más profesional si es miblogchupiguay.com. No te preocupes, esta es quizás la inversión más pequeña que necesites: 10-15 €/año.
Si lo que tienes entre manos es un blog profesional, quizás estos artículos se te queden cortos o te sirvan únicamente como introducción. En ese caso te aconsejo que acudas a obtener ayuda profesional, tanto para marketing online como para desarrollo web (crear/modificar un tema, un plugin, etc.). Si necesitas esa ayuda profesional puedes contar conmigo.
Te espero la siguiente semana con el artículo sobre SEO.
» Leer más, comentarios, etc...
Variable not found
Enlaces interesantes 55
Octubre 17th, 2011 - [Enlace local]
Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 9 al 16 de octubre de 2011. Espero que os resulten interesantes. :-)
- 6 Super jQuery Slider Scripts and Tutorials
JS News & Resources - Conectar una Azure Cloud Drive directamente a tu equipo
David Rodríguez - Novedades para SQL Azure
Ibon Landa - [WebCast] Seguridad de aplicaciones Web: las técnicas más interesantes para que no hackeen tu aplicación, con José Manuel Alarcón
AUGES - Cómo detectar el cierre o la salida de una página Web
José Manuel Alarcón - The Developer’s Guide to AppFabric (ebook)
Adam Smith - Optimizing ASP.NET MVC3 Routing
Sam Saffron - AutoMapper (I) Flattening
Luis Ruiz Pavón - Intellitrace como tu sistema de rastreo
Unai Zorrilla - Three simple steps to create Azure tables
Neil Mackenzie - Naked objects goes open source
Naked objects group - ASP.NET MVC – Template Helpers
Sebis - Modernizr.js: feature detection
K. Scott Allen - SQL Azure DataSync Preview. Sincronizando… ¡Step by step!
Juan Luis Guerrero - Essential jQuery Plugin Patterns
Addy Osmani, vía Marc Rubiño - .NET Math Library
BlackWasp - ParallelLoopState and Parallel.ForEach
K. Scott Allen - Loading jQuery Consistently in a .NET Web App
Rick Strahl - El próximo martes 18, WebCast: Gestión de excepciones en .NET, con Jorge Serrano
SecondNug - Preventing CSRF With Ajax
Phil Haack - EF 4.2 Release Candidate Available
Vía Juan Carlos González - RFC: New Beta.ASP.net website
Scott Hanselman - Si trabajas con javascript seguro que conoces JSLint, pero sabías que lo tienes para Visual Studio?
Vía José Bonnin - Steve Jobs: ¿visionario o un tipo observador e inquieto?
José Manuel Alarcón - Usando querystring en ASP.NET MVC
Eduard Tomás - Range Requests in ASP.NET MVC – RangeFileResult
Tomasz Pęczek
Publicado en: Variable not found
» Leer más, comentarios, etc...
MadeInFlex
SAP Tech Ed y SAP Train Race
Octubre 16th, 2011 - [Enlace local]
Adobe anuncia la conferencia SAP TechEd, que te permitirá ponerte al día con las soluciones SAP.
SAP TechEd es una conferencia técnica para los profesionales que desarrollan con sistemas SAP. Mediante esta conferencia podrás aprovechar la potencia de la tecnología SAP NetWeaver y SAP BusinessObjects para dar un valor añadido a tu conocimiento: aprende como implementar soluciones para tu empresa, usando la tecnología SAP.
En esta conferencia aprenderás directamente de los expertos SAP, a través de centenares de sesiones para todos los niveles, desde el más básico hasta el más experto.
La conferencia estará compuesta de:
- workshops: realizando ejercicios y clases de entrenamiento con expertos SAP.
- demostraciones de los expertos: en la que nos expondrán buenas prácticas, trucos y muestras de código para resolver distintas situaciones.
- exposiciones: para afrontar situaciones reales mediante las soluciones SAP.
- SAP executive keynote: se nos mostrará una visión al futuro de la tecnología SAP.
- Podrás conocer a los conferenciantes y aprender de ellos en las sesiones educativas.
- Sesiones de expertos: disfruta de los expertos SAP en grupos reducidos.
- Soluciones de diferentes partners: nos mostrarán su conocimiento a la hora de manejar el ecosistema SAP.
Esta conferencia tendrá lugar del 8 al 10 de noviembre en Madrid.
Más información aquí.
Además, Adobe da soporte al evento SAP Train Race que tendrá lugar en Madrid, también en noviembre. Serán tres días que formarán un curso diseñado para ayudar a los desarrolladores a crear aplicaciones empresariales basadas en la plataforma SAP NetWeaver Gateway y Flash Builder.
La plataforma SAP NetWeaver Gateway es un framework que permite a los desarrolladores crear aplicaciones ligadas al software SAP, aplicaciones de amplia gama, como redes sociales, plataformas colaborativas, aplicaciones mobile y aplicaciones web.
El enlace donde podrás consultar más información es este.
Anímate
» Leer más, comentarios, etc...
Koalite's blog
¿Se puede ser demasiado ágil?
Octubre 16th, 2011 - [Enlace local]
Hace mucho tiempo que me convencieron las ideas de la metodologías ágiles para desarrollar software y desde entonces las he ido aplicando, con bastante éxito, a los proyectos de desarrollo que he llevado a cabo.
Nunca las he seguido “al pie de la letra”, sino que más bien las he ido adaptando a mis necesidades y al flujo de trabajo de mi equipo, pero en general el resultado ha sido bueno.
Algunas de esas prácticas las he ido refinando con el tiempo, como el uso de test unitarios, ya sea mediante TDD, BDD o simplemente escribiendo los tests a la vez que el código.
Otras han demostado su valor desde el principio y me han permitido mejorar mucho la calidad del software, como la integración continua o la programación en pareja.
No obstante, he encontrado casos en los que ser demasiado ágil puede ser un problema.
Una de las cosas que promueven las metologías ágiles es el Release early, release often, es decir, liberar pronto y liberar frecuentemente. La idea es que cuanto antes puedas poner en producción lo desarrollado, antes estará generando valor ese desarrollo. Esto a priori parece una idea muy buena (y lo es), pero no está exenta de problemas, sobre todo dependiendo del tipo de proyecto que estemos desarrollando.
Liberando con demasiada frecuencia
Si estamos desarrollando una aplicación web, es fácil liberar frecuentemente puesto que toda nuestra aplicación estará online. Cuando despleguemos los cambios en los servidores de producción, los cambios estarán disponibles automáticamente.
Esto puede ser confuso para los usuarios si no lo hacemos con cuidado, porque si los cambios son grandes, pueden tener que volver a aprender a manejar la aplicación, no encontrar las opciones que ya conocían, etc. Para mi, un ejemplo claro de esto es Google Analytics, que cada poco tiempo cambia el interface y tienes que dedicar un rato para encontrar las 4 opciones que acabas usando todos los días.
Aun así, si se hace con un poco de cuidado, en el mundo web es una alternativa viable.
Sin embargo, cuando se trata de aplicaciones instaladas en el cliente (ya sea un PC, un Smartphone o lo que se os ocurra), esta idea de liberar versiones frecuentemente implica varias cosas.
En una aplicación cliente hay que tener un sistema de actualizaciones automáticas desde el primer día. A no ser que nuestros usuarios sean muy avanzados y estén dispuestos a preocuparse por actualizar el softare manualmente (cosa que nunca casi nunca ocurre), si no tenemos listo un sistema de actualizaciones automáticas jamás se actualizarán a las nuevas versiones.
¿Por qué es importante mantenerlos actualizados? Porque al final de una forma u otra tenemos que dar soporte a la aplicación y no hay nada más frustrante que recibir incidencias por fallos que están corregidos en versiones posteriores. Es una mala manera de gastar recursos de soporte.
Además, el sistema de actualizaciones automáticas se convierte en una parte fundamental de la aplicación, ya que toda nuestra teoría de release early, release often se basa en que puedo dar valor cada poco tiempo y mejorarlo en cada actualización, así que mi manera de protegerme frente a fallos e incrementar valor es actualizar la aplicación, pero si el fallo está en el sistema de actualización… estoy perdido.
Liberar demasiado pronto
Cuando se trata de un desarrollo “a medida”, para un cliente concreto, esta idea funciona bastante bien porque permite al cliente disfrutar del software que estamos construyendo lo antes posible, lo que además le facilita darnos su opinión y ajustar el desarrollo para que el producto final sea realmente útil para él.
Realmente, funciona bien si el cliente es consciente de lo que estamos haciendo, es decir, está implicado en el desarrollo y sabe que la versión que le estamos dando es “incompleta” y será mejor dentro de 2 semanas (o cuando acabemos el siguiente sprint).
Sin embargo, cuando se trata de una aplicación estándar, destinada al público en general, muchas veces no podemos permitirnos causar una mala impresión. El usuario de la aplicación, y en esto da igual que sea una aplicación web o una aplicación instalada, no tiene ni idea de si estamos trabajando en mejorar la aplicación o no, no sabe si dentro de 15 días será mucho mejor y aparecerán las 3 funcionalidades que necesita. Y además no le importa. Ni le tiene que importar.
Hoy en día, para resolver cualquier problema es muy fácil encontrar en internet multitud de alternativas. Eso quiere decir que tu aplicación va a competir con muchas otras y, el usuario típico, probará varias y se quedará con una. Si tienes suerte y tu aplicación es una de las que prueba, más te vale que le guste, porque si no le gusta, lo más probable es que no vuelva a probarla durante bastante tiempo. Él no tiene tiempo de revisar cada 2 semanas si has hecho avances o no.
Por supuesto, si eres Apple, o Google, o Microsoft esto no se aplica porque tu equipo de marketing será capaz de generar expectativas durante bastante tiempo (y bastantes versiones), pero si no lo eres, más te vale preocuparte de que el usuario no catalogue directamente tu aplicación como basura.
Es lo mismo que decía Joel Spolsky sobre el lanzamiento de Trello:
couldn’t stop thinking that you never have a second chance to make a first impression. We got 131,000 eyeballs on 9-month-old Trello when we launched, and it was AWESOME, so 22% of them signed up. If we had launched 3-month-old Trello, it would have been NOT SO AWESOME. Maybe even MEH. I don’t want 131,000 eyeballs on MEH.
No puedo dejar de pensar que nunca tienes una segunda oportunidad para causar una primera impresión. Cuando lanzamos de Trello (tras 9 meses de desarrollo) era INCREIBLE y de los 131000 primeros visitantes, el 22% se registro. Si lo hubiésemos lanzado tras 3 meses de desarrollo, hubiera sido NO TAN INCREIBLE. Tal vez incluso ABURRIDO. No quiero 131000 visitas a algo ABURRIDO.
El termino medio entre dos vicios
Decía Aristóteles (y esta debe ser la única frase que todos sabemos de él) que la virtud es el término medio entre dos vicios. En este caso se puede aplicar perfectamente.
Por una parte, no tiene sentido encerrarnos en nuestra torre de marfil durante 18 meses desarrollando funcionalidad sobre funcionalidad hasta generar El Producto Perfecto ™, sólo para darnos cuenta al liberarlo de que no es lo que la gente necesita. Que nuestra forma de ver las cosas no es la misma que la de nuestros usuarios. Para eso es preferible fallar rápido y perder menos tiempo.
Pero por otra parte, si después de un mes liberamos un producto incompleto, inacabado, sin un mínimo de atractivo, muchos de nuestros usuarios potenciales lo verán, lo despreciarán y nunca más volverán a él.
En cuanto a la frecuencia de liberación, necesitamos alcanzar un equilibrio entre volver loco al usuario con nuevas versiones (como hace Java que cada día quiere instalarme una actualización nueva) y darle la impresión de que nuestro producto está estancado y descontinuado.
Encontrar el punto justo para liberar un producto es todo un arte y me temo que no hay recetas mágicas para encontrarlo. Hay factores que pueden ayudar, pero no garantizan nada. Algunas de las cosas que ayudan a encontrar el momento:
- Conocer la competencia para ver a qué nos enfrentamos.
- Conocer a los usuarios para intentar saber qué necesitan.
- Tener claras las funcionalidades de cada versión para evitar alargar el desarrollo eternamente.
- Hacer betas cerradas/controladas para no perder todos los usuarios a la vez
.
Siguiendo estos pasos no tendremos garantías absolutas, pero al menos estaremos controlando un poco más los riesgos que asumimos.
» Leer más, comentarios, etc...
El blog de pico.dev
Ejemplo sencillo con JavaCC de un analizador léxico y sintáctico
Octubre 15th, 2011 - [Enlace local]

Cuando nos enfrentamos a un problema de procesar una expresión debemos tener en cuenta primeramente dos cosas: cual es su léxico (las palabras que lo forman) y su sintaxis (las reglas que definen el orden del léxico). Más tarde por otra parte para procesar la expresión necesitaremos de acciones léxicas y sintácticas que es código que se ejecutará para realizar las tareas que necesitemos al procesar la expresión.
Para facilitar la tarea existen los compiladores como resultado de la invención de los primeros lenguajes y aunque parecen algo complejo de hacer no lo son tanto como desarrollar un algoritmo específico. JavaCC es una herramienta que nos permite definir el léxico de una expresión o lenguaje, la sintaxis del mismo y las acciones léxicas y sintácticas generando posteriormente con la definción de estas cosas una serie de archivos .java con el código fuente de un analizador léxico, sintáctico y otra serie de archivos .java de utilidad para los mismos.
Supongamos que tenemos una aplicación en la que el usuario tiene una caja de búsqueda en la que puede introducir una serie de palabras separadas por espacios, en la que también puede agrupar varias palabas rodeándolas con " y también puede introducir fechas en varios formatos y con distintos separadores para el día, mes y año pudiendo especificar día, mes y año, solo mes y año, solo el mes o solo el año, por ejemplo dd.MMM.yyyy, dd/MMMM/yyyy, MMMM-dd-yyyy, MMM.yyyy, MMM, yyyy, ... Para complicarlo aún más los meses pueden estar en diferentes idiomas. Un ejemplo de expresión podría ser: «"real madrid" enero.2012 febrero.2012 fútbol» en la que intenta buscar elementos relacionados con el real madrid y fútbol y en los meses de enero o febrero de 2012.
Veamos el código fuente de nuestro pequeño compilador cuya misión sera interpretar la expresión de la mejor de las formas y devolver un objeto org.hibernate.criterion.Criterion con el que podremos hacer una búsqueda en Hibernate según los criterios de la expresión. El compilador está dividido en varias partes:
PARSER_BEGIN y PARSE_END: define el nombre de nuestro analizador e incluye métodos de utilidad (en perfecto código Java) que será incluidos en el analizador sintático sin modificar y que podremos usar desde las acciones sintácticas. Los métodos importantes de esta primera parte son los constructores (JavaCC inserta unos pero como vemos podemos definir más), el método main, buildCriterionTermino y buildCriterionFecha que construirán un Criterion cuando el analizador sintáctico detecte un término o fecha respectivamente, la misión principal de nuestro compilador. Estos métodos no tienen mayor complicación son puro código Java. (en azul).
SKIP y TOKEN: esta parte es la que define el analizador léxico con las palabras de nuestra expresión o lenguaje. Ahí están la forma de las fechas, los términos, el día, mes y año, los separadores. Básicamente son una forma de expresiones regulares para definir cada uno de ellos (en morado).
procesarQuery, procesar, termino, fecha: Son propiamente los métodos del analizador sintáctico y van a definir la sintáxis de nuestro lenguaje. procesar contiene una de las partes más importantes ya que es el punto de partida, va cogiendo los tokens proporcionados por el analizador léxico (que genera JavaCC) y determina si es una fecha, término o algo desconocido. Según lo detectado se ejecuta el bloque de código posterior que va entre {} y que constituye una acción sintáctica. Como se ve la acción sintáctica es perfecto código Java y puede usar las variables definidas en el bloque procesar como ct, ft y r. Después de procesar todos los términos de la expresión se ejecuta otra acción sintáctica que agrupa todos los Criterion recogidos en ct, cf en uno solo y que será lo que devuelve el analizador (en verde).
En la acción sintáctica de termino tenemos que tener en cuenta que el término puede ser un mes (enero, ...) por lo que se intenta procesar como una fecha con buildCriterionFecha y si devuelve algo es que se trataba de un mes sino se procesará como un termino con buildCriterionTermino.
¿Por qué se trata un elemento DESCONOCIDO? Porque sino el analizador sintáctico daría un excepción al no saber lo que es, teminaría y no devolvería nada. De esta forma conseguimos que si una expresión que no se entiende se ignore y se devuelvan al menos el resto de expresiones en el Criterion. Este será el caso de un término fecha mal expresado como «01.enero/2012» donde mezcla diferentes separadores en la misma fecha. Tal como están definidos los tokens, el analizador léxico no sabría que es.
Y eso es lo principal de nuestro compilador. No es tan complicado hacer uno como podría parecer a priori, sin duda mucho más fácil que hacer un algoritmo específico para ello incluso para una expresión tan simple como la tratada, ahora imagínate una que pueda ser como «(<expr>
Esta es una de esas herramientas muy útilies y con la cual sabiendo usarla o al menos tener conocimiento de ella nos puede ahorrar mucho tiempo y conseguir hacer las cosas mejor. Además y dado que lo que genera como resultado son una serie de archivos .java podremos utilizarlos en cualquier entorno, como en alguna administración pública cuyo nombre no citaré aquí y en la que no esta permitido usar librerías no homologadas por ellos, dado que se trata de código fuente y que no tiene dependencias sobre otras librerías no tendremos ningún problema en usar JavaCC en casos como este.
Para compilar el compilador podemos hacerlo con ant con la siguiente tarea (también podemos utilizar los propios comandos de JavaCC):
<javacc target="src/main/java/com/blogspot/elblogdepicodev/jj/Buscador.jj"
outputdirectory="src/main/java/com/blogspot/elblogdepicodev/jj/buscador"
javacchome="/home/[user]/javacc-5.0"/>
Los archivos generados serían:
- Buscador.java
- BuscadorConstants.java
- BuscadorTokenManager.java
- ParseException.java
- SimpleCharStream.java
- Token.java
- TokenMgrError.java
// Buscador.jj
options {
STATIC = false;
}
PARSER_BEGIN(Buscador)
package com.blogspot.elblogdepicodev.jj.buscador;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.IntegerType;
import org.hibernate.type.Type;
public class Buscador {
private static final String[] FORMATOS_FECHAS = new String[] {
"d/MMM/yyyy", "d/MMMM/yyyy", "MMM/d/yyyy", "MMMM/d/yyyy", "MMM/yyyy", "MMMM/yyyy",
"d.MMM.yyyy", "d.MMMM.yyyy", "MMM.d.yyyy", "MMMM.d.yyyy", "MMM.yyyy", "MMMM.yyyy",
"d-MMM-yyyy", "d-MMMM-yyyy", "MMM-d-yyyy", "MMMM-d-yyyy", "MMM-yyyy", "MMMM-yyyy",
"MMM", "MMMM", "yyyy"
};
private Locale locale;
public Buscador(Locale locale) {
this(new StringReader(""), locale);
}
public Buscador(InputStream is, String encoding, Locale locale) {
this(is, encoding);
this.locale = locale;
}
public Buscador(Reader r, Locale locale) {
this(r);
this.locale = locale;
}
public static void main(String[] args) throws ParseException, TokenMgrError {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < args.length; ++i) {
if (i > 0) {
sb.append(" ");
}
sb.append(args[i]);
}
Buscador parser = new Buscador(new Locale("es"));
Criterion criterion = parser.procesarQuery(sb.toString());
System.out.println(criterion);
}
// Utilidades
private Criterion or(List<Criterion> criterions) {
Criterion lhs = null;
for (Criterion criterion : criterions) {
if (lhs == null) {
lhs = criterion;
} else {
lhs = Restrictions.or(lhs, criterion);
}
}
return lhs;
}
private Criterion and(List<criterion> criterions) {
Criterion lhs = null;
for (Criterion criterion : criterions) {
if (lhs == null) {
lhs = criterion;
} else {
lhs = Restrictions.and(lhs, criterion);
}
}
return lhs;
}
private Criterion buildCriterionTermino(String term) {
List<Criterion> coincidencias = new ArrayList<Criterion>();
String t = "%" + term + "%";
coincidencias.add(Restrictions.ilike("nombre", t));
coincidencias.add(Restrictions.ilike("ciudad", t));
coincidencias.add(Restrictions.ilike("direccion", t));
Criterion criterio = or(coincidencias);
return criterio;
}
private Criterion buildCriterionFecha(String term) {
Criterion criterio = null;
for (int i = 0; i < FORMATOS_FECHAS.length; ++i) {
String formatoFecha = FORMATOS_FECHAS[i];
SimpleDateFormat sdf = new SimpleDateFormat(formatoFecha, locale);
// Fecha
try {
Date fecha = sdf.parse(term);
Calendar calendario = Calendar.getInstance(locale);
calendario.setTime(fecha);
switch (i) {
case 0:
case 1:
case 2:
case 3:
case 6:
case 7:
case 8:
case 9:
case 12:
case 13:
case 14:
case 15:
// Día, mes, año
criterio = Restrictions.sqlRestriction("(day({alias}.fecha) = ? and month({alias}.fecha) = ? and year({alias}.fecha) = ?)", new Object[] {
calendario.get(Calendar.DAY_OF_MONTH), calendario.get(Calendar.MONTH) + 1, calendario.get(Calendar.YEAR) }, new Type[] { IntegerType.INSTANCE,
IntegerType.INSTANCE, IntegerType.INSTANCE });
break;
case 4:
case 5:
case 10:
case 11:
case 16:
case 17:
// Mes, año
criterio = Restrictions.sqlRestriction("(month({alias}.fecha) = ? and year({alias}.fecha) = ?)", new Object[] {
calendario.get(Calendar.MONTH) + 1, calendario.get(Calendar.YEAR) }, new Type[] { IntegerType.INSTANCE, IntegerType.INSTANCE });
break;
case 18:
case 19:
// Mes
criterio = Restrictions.sqlRestriction("month({alias}.fecha) = ?", calendario.get(Calendar.MONTH) + 1, IntegerType.INSTANCE);
break;
case 20:
// Año
criterio = Restrictions.sqlRestriction("year({alias}.fecha) = ?", calendario.get(Calendar.YEAR), IntegerType.INSTANCE);
break;
default:
assert (false);
break;
}
} catch (java.text.ParseException e) {
}
if (criterio != null) {
break;
}
}
return criterio;
}
private class CriterionInfo {
public boolean isFecha;
public Criterion criterio;
}
}
PARSER_END(Buscador)
SKIP : { " " | "\t" | "\n" | "\r" | "\r\n" }
TOKEN : { < #NO_SKIP : ~[" ", "\t", "\r", "\n"] > }
TOKEN : { < #SEP1 : "/" > }
TOKEN : { < #SEP2 : "." > }
TOKEN : { < #SEP3 : "-" > }
TOKEN : { < #SEP : (<sep1> | <sep2> | <sep3>) > }
TOKEN : { < #LETRA : ~[" ", "\t", "\r", "\n", "/", ".", "-"] > }
TOKEN : { < #NUM : ["0"-"9"] > }
TOKEN : { < #MES : (<letra>)+ > }
TOKEN : { < #DIA : (<num> | <num><num>) > }
TOKEN : { < #ANO : (<num><num><num><num>) > }
TOKEN : { < FECHA : (
<dia><sep1><mes><sep1><ano> | <mes><sep1><dia><sep1><ano> | <mes><sep1><ano> |
<dia><sep2><mes><sep2><ano> | <mes><sep2><dia><sep2><ano> | <mes><sep2><ano> |
<dia><sep3><mes><sep3><ano> | <mes><sep3><dia><sep3><ano> | <mes><sep3><ano> |
<num><num><num><num>) > }
TOKEN : { < TERMINO : ("\""(~["\""])+"\"" | (<letra>)+) > }
TOKEN : { < DESCONOCIDO : (<no_skip>)+ > }
Criterion procesarQuery(String query) :
{
Criterion criterio = null;
ReInit(new StringReader(query));
}
{
criterio = procesar()
{
return criterio;
}
}
Criterion procesar() :
{
List<Criterion> ct = new ArrayList<Criterion<();
List<Criterion> cf = new ArrayList<Criterion<();
Criterion criterio = null;
CriterionInfo criterioInfo = null;
Token t = null;
}
{
(
criterio = fecha()
{
if (criterio != null) {
cf.add(criterio);
}
//System.out.println(criterio);
}
|
criterioInfo = termino()
{
criterio = criterioInfo.criterio;
if (criterio != null) {
if (criterioInfo.isFecha) {
cf.add(criterio);
} else {
ct.add(criterio);
}
}
//System.out.println(criterio);
}
|
t = <desconocido>
{
//System.out.println(t.image);
}
)*
<eof>
{
List<Criterion> r = new ArrayList<Criterion>();
if (!ct.isEmpty()) {
r.addAll(ct);
}
if (!cf.isEmpty()) {
r.add(or(cf));
}
return (r.isEmpty())?null:and(r);
}
}
CriterionInfo termino() :
{
Token t = null;
}
{
t = <termino>
{
//System.out.println(t.image);
String term = t.image;
CriterionInfo ci = new CriterionInfo();
// Comprobar si se trata de un mes
ci.criterio = buildCriterionFecha(term);
if (ci.criterio != null) {
ci.isFecha = true;
} else {
ci.isFecha = false;
if (term.startsWith("\"") && term.endsWith("\"")) {
term = term.substring(1, term.length() - 1);
}
ci.criterio = buildCriterionTermino(term);
}
return ci;
}
}
Criterion fecha() :
{
Token t = null;
}
{
t = <fecha>
{
String term = t.image;
return buildCriterionFecha(term);
}
}
Referencia:
http://javacc.java.net/
http://www.lpsi.eui.upm.es/webcomp/jgperez/java/IntrodJavaCC.pdf
» Leer más, comentarios, etc...
Picando Código
Dennis Ritchie 1941 – 2011
Octubre 14th, 2011 - [Enlace local]
Hoy me enteré del fallecimiento de Dennis Ritchie. Fue un genio de la ciencia de la computación, responsable del lenguaje de programación C. C no solo se usa para desarrollar aplicaciones, sistemas operativos y sistemas embebidos, sino que es la base del diseño de gran parte de los lenguajes de programación que existen (Java, C++, Perl, PHP, por nombrar alguno).
También fue uno de los principales desarrolladores del sistema operativo UNIX, lo que definió varios conceptos y principios de la computación moderna. De este trabajo se desprenden tanto GNU y Linux como Mac OS X.
Como si esto fuera poco, escribió junto a Brian Kernighan el libro The C Programming Language, conocido como K & R, y uno de los libros más importantes en el mundo de la programación. Además de ser una referencia como manual de un lenguaje de programación, fue el libro que introdujo el ejemplo de “Hello World”.
La sintaxis y formato del código escrito en el libro ha pasado a conocerse como el estilo “K&R” y se usa como convención en el desarrollo de Linux entre otros proyectos.
De más está decir que los aportes de Ritchie al mundo de la informática son invaluables. Y le tocó la hora de su “Goodbye World”.
Vaya el pequeño homenaje desde Picando Código:
#include int main() { printf("Goodbye dmr\n"); return 0; }
[fernando@hoth]$ gcc dmr.c [fernando@hoth]$ ./a.out Goodbye dmr
Un par de citas interesantes de Ritchie que publiqué en Twitter e Identi.ca:
“C is quirky, flawed, and an enormous success.”
Comparte:“UNIX is very simple, it just needs a genius to understand its simplicity.”
» Leer más, comentarios, etc...
Ingenieria de Software / Software Engineering / Project Management / Business Process Management
Manejo de clientes difíciles
Octubre 13th, 2011 - [Enlace local]
Me decían en un curso que la gestión es un arte y creo que hay mucha razón en esto y entre esas actividades artísticas esta el manejo de clientes difíciles, aquí un buen artículo del tema
» Leer más, comentarios, etc...
Javier Pérez
¡Rebelaos! Manifestación 15 de octubre
Octubre 13th, 2011 - [Enlace local]
Por si alguien aún no se ha enterado, se ha convocado una manifestación global este sábado 15 de octubre. a las 18:00 desde Sol (ver convocatorias en otras provincias) ¿Por qué? ¿Aún te haces esa pregunta? Cito el escrito de Democracia Real Ya:
El 15 de octubre personas de todo el mundo tomarán las calles y las plazas. Desde América a Asia, desde África a Europa, la gente se está levantando para reclamar sus derechos y pedir una auténtica democracia. Ahora ha llegado el momento de unirnos todos en una protesta no violenta a escala global.
Los poderes establecidos actúan en beneficio de unos pocos, desoyendo la voluntad de la gran mayoría, sin importarles los costes humanos o ecológicos que tengamos que pagar. Hay que poner fin a esta intolerable situación.
Unidos en una sola voz, haremos saber a los políticos, y a las élites financieras a las que sirven, que ahora somos nosotros, la gente, quienes decidiremos nuestro futuro.
No somos mercancía en manos de políticos y banqueros que no nos representan.
El 15 de octubre nos encontraremos en las calles para poner en marcha el cambio global que queremos. Nos manifestaremos pacíficamente, debatiremos y nos organizaremos hasta lograrlo.
Es hora que nos unamos. Es hora que nos escuchen.
¡Tomemos las calles del mundo el 15 de octubre!
Y si eso no te convence, prueba con este vídeo:
» Leer más, comentarios, etc...
Javier Pérez
Plataforma por el Civismo
Octubre 13th, 2011 - [Enlace local]
civismo: 2. Comportamiento respetuoso del ciudadano con las normas de convivencia pública.
Quien ha viajado más allá de Fuenlabrada lo sabe. Los españoles somos unos incívicos, no sabemos convivir, no tenemos ni la más mínima cortesía, no respetamos a nada ni a nadie. Y no estoy hablando de la juventud, o al menos no exclusivamente, sino de todas las edades, desde los más pequeñitos (a los que está de moda consentirles absolutamente todo) hasta los más mayores (que por su edad se creen con derecho a todo). Y sí, he puesto dos enlaces en un mismo párrafo a Don Arturo Pérez-Reverte, que es para mí casi un dios en esta cuestión.
Quien me conoce o al menos conoce mi blog, sabe que soy muy estricto en el tema respeto. No han sido pocos los artículos que he dedicado a vejar al incívico o maleducado. Pero mi lucha va más allá de este blog. En la calle trato de predicar con el ejemplo, lo que es la mejor manera posible de transformar a una sociedad, sobre todo con mi hija. Trato de transmitirle unos valores que nunca jamás los encontrará en la calle, ni siquiera en el colegio (tampoco es su lugar), y la pobre se debate en una horrible lucha interna entre lo que su padre le dice y hace, y lo que ve en la calle. Si lleva mis genes se revelará contra todo y todos, incluidas mis lecciones, pero no voy a desistir.
En esta lucha personal e intransferible (todos deberíamos hacer esta guerra) decidí grabar en vídeo al incívico y colgarlo de YouTube para que todo el mundo pudiera verlos. Es decir, ayudarme de la presión social para que mediante su dedo acusador cohiba a ese incívico. Hasta el momento he grabado tres vídeos (#1 y #2), pero el que más repercusión ha tenido ha sido el que grabé en el carril bici:
En YouTube va por las 20.000 reproducciones, en menéame obtuvo casi 2.000 meneos y 390 comentarios, lo han publicado en numerosos blogs y foros, e incluso lo emitieron en los informativos de Telecinco:
Una repercusión que no me esperaba en absoluto, pero de la que estoy muy orgulloso, porque eso era lo que pretendía, y lo conseguí.
Después de este éxito decidí que ya era hora de que existiera una asociación que luchara como un auténtico lobby por el civismo en España, para que se hagan respetar unas mínimas normas de convivencia, para que se persiga al incívico y se le castigue con todas las de la ley, o al menos con toda la presión de la sociedad. Y así nació Plataforma por el Civismo.
De momento sólo tiene una página en Facebook, y un blog que espero terminar de diseñar y maquetar en breve, quizás con la ayuda de algún colaborador, donde poder hacer denuncia social de todos los actos incívicos que se produzcan.
La unión nos da la fuerza, y en este caso es fundamental. La presión social que se requiere para transformar a la propia sociedad sólo se consigue mediante la unión. Muchas afiladas miradas de reprobación hacia una persona que ha tirado un papel al suelo es el mayor arma posible para luchar contra el incivismo.
Así que, si estás interesado en este problema, por favor únete, juntos podemos cambiar España. Únete a Plataforma por el Civismo.






