Archive for the 'desarrollo' Category

26
Jun
08

versión móvil

Acabamos de hacer pública nuestra versión para móviles. Son tres vistas, la caja de búsqueda, los resultados de la búsqueda y la página de servicio.

Para hacer las páginas más ligeras hemos eliminado todas las imágenes y opiniones. De cada servicio dejamos sólo nombre, dirección, teléfono y el mapa descargado como una imagen.

La aplicación está hecha en grails. Queríamos probar grails porque se integra muy bien con librerías y otros desarrollos que tenemos hechos en java. De hecho seguro que cuando esta aplicación crezca usaremos esas magníficas capacidades, pero ahora mismo esta aplicación sólo se comunica con el buscador por HTTP y con la base de datos por JDBC. Así que seguramente la única excusa que se nos ocurre para haber usado grails es porque nos apetecía probarlo :).

La experiencia ha sido buena aunque hemos echado de menos una buena integración con IDEs, en concreto con Eclipse. No obstante tendremos que programar más para fundamentar mejor nuestra evaluación.

Implementamos un Device Filter para filtrar a los Iphones por el User-Agent, a estos se les ofrecen las mismas vistas que al resto de los dispositivos excepto por las hojas de estilo y los scripts de Javascript que son especiales para aprovechar las capacidades de los navegadores Safari (WebKit):

  • Manejo de eventos especiales generados por webkit como el Orientation Event, para modificar la interfaz según la orientación del aparato.

Para el resto de dispositivos las vistas se sirven con XHTML Mobile Profile 1.0; usamos atributos acceskeys en algunos enlaces para habilitar la navegación a través del teclado del dispositivo y la función de hacer llamada de la especificación WTAI (Wireless Telephony Application Interface) para que los dispositivos reconozcan números de teléfono en el contenido de las páginas y permitan hacer llamadas directamente.

20
May
08

Simplificación de polígonos con el algoritmo Douglas-Peucker

Hace bastante tiempo ya nos encontramos con un problema del que no teníamos ni idea: nuestra fuente de datos nos pasaba datos de áreas geográficas (más concreto, los contornos) como listas de miles de puntos. En aquel entonces, la API de Google Maps dejaba frito el navegador cuando se intentaba dibujar un polígono con tal número de vértices (hoy ha mejorado y en vez de pintar un polígono vía Javascript, la API te tira una imagen a partir de la segunda petición).

¿Qué tuvimos que hacer? Reducir el número de puntos que definían cada uno de los polígonos intentando ser lo más fieles posible a la forma original porque pintar una provincia cualquiera como un cuadrado no es solución. No sólo teníamos datos de provincias: también teníamos de distritos y barrios. Y eso hacía que esta simplificación de polígonos fuera algo bastante intratable de hacer a mano. Fue así como descubrimos que existía una forma de hacerlo automáticamente y cuyo algoritmo fue desarrollado por David Douglas & Thomas Peucker y es conocido como Douglas-Peucker polyline simplification algorythm.

Partimos de un trozo de código en Pascal que encontramos en algún lugar y lo portamos a Python, que era el lenguaje con el que hicimos todo el script de importación de datos. Se quedó pendiente de publicación el asunto, ya que en su día nadie había portado dicho código a Python (ni Ruby ni Perl ni ningún lenguaje de script medianamente actual). El caso es que eso ha sido hasta hace un par de semanas Schuyler Erle publicó su versión en Mapping Hacks. Su código es mucho más bonito que el nuestro, así que nos ahorraremos el attachment 😉

30
Abr
08

Spring 2.5 y los filtros de contexto

El cambio a spring 2.5 conlleva una nueva forma de cargar tus clases como beans, lo que ellos llaman contexto. Este contexto es el responsable de añadir como beans las clases que tengas marcadas con las anotaciones que spring te da de serie(@Component, @Controller, @Service, @Repository). Si buceamos un poco en el código de spring podemos ver que la clase encargada de hacer esto es ClassPathBeanDefinitionScanner.java. Esta clase tiene implementada una pequeña jerarquía de filtros para añadir o quitar clases del contexto cuando arranca nuestra aplicación. Por defecto, añade todas las clases que estén marcadas con las anotaciones que hemos visto anteriormente:


  this.includeFilters.add(new AnnotationTypeFilter(Component.class));

Ahora vamos a ver las opciones que nos da el framework para añadir clases a ese contexto. En su documentación podemos ver un claro ejemplo de como añadir una nueva anotación:


  <context:component-scan>
    <context:include-filter type="annotation"
      expression="CustomAnnotation"/>
  </context:component-scan>

Lo que viene a decir el xml es que al contexto le vamos a añadir un filtro de tipo anotación y para todas las clases que estén marcadas con la anotación que va dentro del atributo expression.

Con lo que él internamente hará algo tal que así:


  this.includeFilters.add(new AnnotationTypeFilter(CustomAnnotation.class));

Lo que no se explica en la documentación es que por defecto, la clase que se encarga de parsear el contexto, ComponentScanBeanDefinitionParser.java, también soporta otros tipos de filtros además del de anotaciones.

El más sencillo sería el filtro de asignación, que simplemente añadiría una clase o un grupo de clases que extiendan o implementen algo común:


  <context:component-scan>
    <context:include-filter type="assignable"
      expression="org.myapp.IService"/>
  </context:component-scan>

Con este código se añadirían todas las clases que extendieran de la interfaz org.myapp.IService.

Otro de los filtros que soporta es por expresiones regulares, con este filtro spring cargará en el contexto las clases que coincidan con una expresión regular determinada:


  <context:component-scan>
    <context:include-filter type="regex"
      expression="(Service|Controller)\w+"/>
  </context:component-scan>

Con este código se cargarán todas clases que empiecen por Service o Coltroller.

Por último, tenemos un filtro un poco más complejo que se encarga de evaluar expresiones propias de Aspect Oriented Programming(AOP):


  <context:component-scan>
    <context:include-filter type="aspectj"
      expression="Service || Controller"/>
  </context:component-scan>

Con lo que cargaremos todas las clases que extiendan o implementen la clase Service o Controller.

La verdad es que con el grupo de anotaciones que spring trae de serie es más que suficiente para resolver la mayoría de los problemas pero nos podemos encontrar en escenarios donde no queremos tener como dependencia spring en una clase que puede ser utilizada tanto por spring como por otra aplicación o módulo que no use spring, con lo que acceder a los filtros del contexto nos vendrá muy bien.

05
Feb
08

JBoss borra los logs al arrancar

En realidad no es JBoss el que se carga los logs, es log4j, y la solución es poner a false el parámetro append del DailyRollingFileAppender en el log4j.xml, o sea:

<appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
...
<param name="Append" value="true"/>

De esa forma los ficheros no se sobrescriben al rearrancar.