f Skip to main content

La presente entrada tiene como objetivo presentar una introducción a las anotaciones activas con el lenguaje Xtend, y cómo estás pueden permitir reducir el código necesario para desarrollar una funcionalidad determinada.

Xtend es un lenguaje de programación estáticamente tipado que compila código Java, el cual puede ser configurado para funcionar hasta con Java 5. El escribir código con xtend también permite reducir los tiempos de desarrollo, ya que, su sintaxis es mucho más concisa que java (Incluyendo Java 8).
Es de anotar que, el presente artículo no pretende explicar el funcionamiento del lenguaje (expresiones lambda, métodos de extensión, sobrecarga de operadores, entre otros), sino que se centrará en el uso de las anotaciones activas como medida para la reducción de código repetitivo. Si desea conocer más sobre el lenguaje, aquí encuentra la documentación provista por eclipse

Las anotaciones activas son mecanismos provistos por el lenguaje para participar en el proceso de traducción de código xtend a código java. Una anotación activa es en esencia solo una anotación, la cual se encuentra a su vez anotada con la anotación @Active(procesador), cuenta con un solo parámetro y un procesador de la anotación.

El procesador de la anotación debe implementar una de las clases definidas por xtend para el ciclo de vida del proceso de transformación:

El ciclo de vida del proceso de transformación se compone de 4 etapas:

  • Registro de elementos globales: en esta etapa se definen todas las clases o interfaces adicionales a la clase anotada. Por cada uno de los elementos registrados, se crea el archivo .java asociado
  • Transformación: en esta etapa se puede acceder y realizar modificaciones sobre el código java generado
  • Validación: en esta etapa se puede acceder al proceso de validación, aunque gran parte de esto se puede hacer en los dos pasos anteriores
  • Generación de código: permite participar en el proceso de escritura y actualización de archivos (por ejemplo, la creación de archivos properties, xml, u otros), este paso solo se ejecuta al guardar

Pero, ¿Cómo puede esto ayudar a acelerar el proceso de desarrollo de software?, empecemos por mencionar algunas de las anotaciones activas que vienen incluidas en la base de Xtend.

  1. @Accesor: es una anotación que puede aplicarse a una clase o a un campo y genera los getters y setters para el campo según sea necesario, se puede controlar tanto si se genera el getter como el setter o si sólo se genera uno, además, de poder controlar la visibilidad del campo

En Java

En Xtend

En este ejemplo podemos ver como solo con esta anotación activa sencilla, pasamos de 29 líneas de código a 7.

2. @Data: esta anotación permite la creación de objetos de valor, solo es necesario declarar los campos y en el código java se generarán todos los campos como final, getter para cada campo, un constructor con todos los atributos, el método toString y los métodos equals y hashCode.

En Java

En Xtend

En este caso vemos como 4 líneas de código mediante la anterior anotación, se convierten en 51 líneas de código.

3. @Delegate: esta anotación permite definir métodos sobreescritos de una interfaz en base a una instancia de la clase que implementa la interfaz de la clase anotada.

En Java

En Xtend

Es de anotar que estos ejemplos son anotaciones simples, las cuales se centran solo en la fase 2 del ciclo de vida de las anotaciones activas (proceso de transformación).

En cuanto a uso en proyectos reales, además de lo anterior, gracias a las anotaciones activas, pudimos pasar del siguiente código java para la exposición de un RPC con GWT (3 archivos.java, 2 interfaces y una clase):

Al siguiente código en xtend:

En este código se puede ver como toda la complejidad intrínseca del código java se reduce, además, simplifica la mantenibilidad al tener que mantener un solo archivo en lugar de 3. Todo el código repetitivo se traslada a la anotación y siguiendo el ciclo de vida de las anotaciones activas hace lo siguiente:

  1. Registra las dos interfaces requeridas por gwt en el paso 1 del proceso
  2. En el paso 2, modifica la clase CotizadorRemoteServiceImpl haciéndolo extender CotizadorRemoteServiceServlet e implementar CotizadorRemoteService. Además, valida que la clase se encuentre en el package “server” que debe ser la ubicación por defecto en GWT al ser una implementación de un RPC

Entre otras anotaciones, una de las que mayores simplificaciones trajo fue la de la integración con los UiBinder, también de gwt, en estos, se parte de un archivo xml, el cual se asocia a un código java que define la implementación completa. Por ejemplo, gracias a las anotaciones activas pasamos a:

Xml común tanto a la solución java como a la solución con xtend

En Java

En Xtend

Estas no son las únicas anotaciones definidas y usadas en el proyecto, pero muestran una parte de lo mucho que se simplifica la escritura de código y, a su vez, se mejoraba la mantenibilidad.

Se explicará a continuación la implementación de una anotación, cuyo fin es partir de una clase X a extraer todos sus métodos públicos hacia una interfaz, y hacer que la clase X implemente la interfaz Y.

Primero debemos registrar la interface que se va a crear en el paso número 1 del proceso (registro de elementos globales):

En este caso vemos el uso de context.registerInterface, este método permite definir una interfaz que será generada en la aplicación, además, el contexto tiene métodos adicionales para generar otros tipos como son: clases con registerClass, anotaciones con registerAnnotationType, Enum con registerEnumerationType.

Luego del proceso anterior pasamos al segundo paso del ciclo de vida; transformar la clase para esto:

En este caso vemos como pasamos del contexto de RegisterGlobalContext a TransformationContext.

El primer paso en este método es buscar la interface en el contexto mediante findInterface, debemos tener en cuenta que, si no se hubiera registrado en el primer paso, el método no se podría encontrar ni usar el tipo.

Luego, se asocia la interfaz generada con el código Xtend donde está la anotación, para permitir al IDE funcionalidades como ir a declaración y la vista de OutLine.

El siguiente paso del código nos muestra cómo modificamos la clase anotada y accedemos a la lista de interfaces implementadas y adicionamos la interfaz definida por nosotros.

Luego, buscamos todos los métodos públicos de la clase y los agregamos a la interfaz que fue creada en el método anterior.
Con estas líneas de código lo que estamos haciendo es que al escribir esto:

Se genere esto:

Este es un ejemplo bastante sencillo del proceso de transformación de una clase, pero da una visión general de la funcionalidad que provee xtend para la generación de código y la forma en que, a partir de un código “pequeño” se puede generar un código robusto, permitiendo abstraer además, complejidades o elementos repetitivos con el fin de aumentar la productividad del desarrollador.

roger.perez

Ingeniero desarrollador en Ceiba Software con 4 años de experiencia en desarrollo de aplicaciones bajo el lenguaje Java y otros.

Déjanos tu comentario

Share via
Copy link