FACULTAD DE INFORMÁTICA Universidad Politécnica de Madrid
TRABAJO FIN DE CARRERA Desarrollo de gadgets integrados en la plataforma EzWeb, para visualizar repositorios “git” locales y hospedados en el servicio web GitHub.
Autor Mario Mira Boronat
Tutora Genoveva López Gómez
Junio, 2010
AGRADECIMIENTOS
En primer lugar me gustaría agradecer a mi familia por apoyarme siempre desde que era pequeño e infundirme los valores que han hecho posible que llegara hasta aquí y terminase esta empresa que es finalizar una carrera universitaria. Concretamente a mis padres por su soporte incondicional y a mis hermanos por estar a mi lado cuando los he necesitado y cuando no los he necesitado, también. En segundo lugar agradecer también a mi novia, Estefanía, por entender los peores momentos en los que uno no ve el fin de sus estudios y echarme una mano a sobrellevarlos. Por último, pero no por ello menos importante, agradezco profundamente a mis compañeros del laboratorio Manuel de la Iglesia, Iñaqui Rodríguez y Javier López, que me han guiado de forma vital en la realización de este proyecto; al igual que a mi tutora, Genoveva López, ya que sin ella la realización del mismo habría sido imposible. A todos ellos y a todos los demás que de alguna forma u otra me han apoyado, gracias.
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Índice 1. Introducción y objetivos ........................................... 1 1.1. Presentación ............................................................... 1 1.2. Objetivos ................................................................... 1 1.3. Estructura del documento ............................................. 2 1.4. Visión general del proyecto ........................................... 2
2. Estado del arte .......................................................... 5 2.1. Plataformas de Mashup ................................................. 5 2.1.1. Plataformas de Mashup de presentación .......................... 6 2.1.1.1. Gadget...................................................................................................... 7
2.1.2. Plataformas de Mashup de datos .................................... 8 2.1.3. EzWeb, plataforma de Mashup empresarial .................... 10 2.1.3.1. Estructura de EzWeb .............................................................................. 13
2.2. Repositorios de código ................................................. 16 2.2.1. Git ............................................................................ 16 2.2.2. Github ...................................................................... 18
2.3. Tecnologías ............................................................... 19 2.3.1. Javascript .................................................................. 19 2.3.2. HTML ........................................................................ 19 2.3.4. CSS .......................................................................... 20 2.3.5. Python ...................................................................... 21 2.3.6. JSON ........................................................................ 22
i
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
2.3.7. REST ........................................................................ 23 2.3.8. El Framework Django .................................................. 25 2.3.8.1. Estructura de EzWeb ............................................................................... 25
3. Diseño e implementación ....................................... 26 3.1. Visión general de la solución ........................................ 26 3.2. Adaptador(API) .......................................................... 38 3.2.1. Especificación ............................................................ 38 3.2.2. Diseño del adaptador .................................................. 39 3.2.3. Implementación del adaptador ..................................... 41 3.2.3.1. MET. 1 – Api ............................................................................................ 41 3.2.3.2. MET. 2 – Get_directory ........................................................................... 43 3.2.3.3. MET. 3 – Get_branches ........................................................................... 45 3.2.3.4. MET. 4 – Get_commits ............................................................................ 47 3.2.3.5. MET. 5 – Get_head .................................................................................. 49 3.2.3.6. MET. 6 – Get_tree ................................................................................... 52 3.2.3.7. MET. 7 – Get_blob ................................................................................... 54 3.2.3.8. MET. 8 – Get_branches_github ............................................................... 56 3.2.3.9. MET. 9 – Get_commits_github ................................................................ 58 3.2.3.10. MET. 10 – Get_tree_github ................................................................... 61 3.2.3.11. MET. 11 – Get_blob_github ................................................................... 63
3.3. Gadgets .................................................................... 66 3.3.1. Git-file ...................................................................... 67 3.3.1.1. Captura de Requisitos ............................................................................. 67 3.3.1.1.1. Actores.......................................................................................... 68 3.3.1.1.2. Identificación y descripción de los casos de uso ............................. 68 3.3.1.1.3. Diagramas de contexto .................................................................. 69
ii
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.1.3.1. Iniciar_gadget ...................................................................... 70 3.3.1.1.3.2. Mostrar_fichero ................................................................... 71 3.3.1.1.3.3. Modificar_tamaño................................................................ 72 3.3.1.2. Diseño .................................................................................................... 73 3.3.1.2.1. Diagrama de secuencia para “Iniciar gadget” ................................ 73 3.3.1.2.2. Diagrama de secuencia para “Mostrar fichero” ............................. 74 3.3.1.2.3. Diagrama de secuencia para “Iniciar gadget” ................................ 75 3.3.1.3. Implementación ..................................................................................... 76 3.3.1.3.1. Clases ........................................................................................... 76 3.3.1.3.2. Métodos por caso de uso .............................................................. 77 3.3.1.3.2.1. Iniciar_gadget ...................................................................... 77 3.3.1.3.2.2. Mostrar_fichero ................................................................... 80 3.3.1.3.2.3. Modificar_tamaño................................................................ 84 3.3.1.3.3. Template ...................................................................................... 85 3.3.1.3.3.1. Propiedades ......................................................................... 87 3.3.1.3.3.2. Wiring .................................................................................. 88 3.3.1.3.3.3. Contexto .............................................................................. 89 3.3.1.3.4. Interfaz de usuario........................................................................ 89
3.3.2. Git-tree ..................................................................... 93 3.3.2.1. Captura de Requisitos ............................................................................. 93 3.3.2.1.1. Actores ......................................................................................... 94 3.3.2.1.2. Identificación y descripción de los casos de uso ............................ 94 3.3.2.1.3. Diagramas de contexto ................................................................. 97 3.3.2.1.3.1. Iniciar_gadget ...................................................................... 97 3.3.2.1.3.2. Mostrar_fichero ................................................................... 98 3.3.2.1.3.3. Expandir_arbol ..................................................................... 99 3.3.2.1.3.4. Enviar_fichero .................................................................... 100 3.3.2.1.3.5. Sincronizar ......................................................................... 101 3.3.2.1.3.6. Modificar_tamaño.............................................................. 101
iii
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.2.2. Diseño ................................................................................................... 102 3.3.2.2.1. Diagrama de secuencia para “Iniciar gadget” ............................... 102 3.3.2.2.2. Diagrama de secuencia para “Mostrar árbol” .............................. 103 3.3.2.2.3. Diagrama de secuencia para “Expandir árbol” ............................. 104 3.3.2.2.4. Diagrama de secuencia para “Enviar Fichero” .............................. 105 3.3.2.2.5. Diagrama de secuencia para “Sincronizar” ................................... 105 3.3.2.2.6. Diagrama de secuencia para “Modificar Tamaño” ....................... 106 3.3.2.3. Implementación .................................................................................... 107 3.3.2.3.1. Clases .......................................................................................... 107 3.3.2.3.2. Métodos por caso de uso ............................................................ 108 3.3.2.3.2.1. Iniciar_gadget ..................................................................... 108 3.3.2.3.2.2. Mostrar_arbol..................................................................... 112 3.3.2.3.2.3. Expandir_arbol.................................................................... 117 3.3.2.3.2.4. Enviar_fichero..................................................................... 118 3.3.2.3.2.5. Sincronizar .......................................................................... 119 3.3.2.3.2.6. Modificar_tamaño .............................................................. 119 3.3.2.3.3. Template ..................................................................................... 120 3.3.2.3.3.1. Propiedades ........................................................................ 122 3.3.2.3.3.2. Wiring ................................................................................. 123 3.3.2.3.3.3. Contexto ............................................................................. 124 3.3.2.3.4. Interfaz de usuario ...................................................................... 125
3.3.3. Git-commits .............................................................. 129 3.3.3.1. Captura de Requisitos ........................................................................... 129 3.3.3.1.1. Actores........................................................................................ 129 3.3.3.1.2. Identificación y descripción de los casos de uso ........................... 130 3.3.3.1.3. Diagramas de contexto ................................................................ 134 3.3.3.1.3.1. Iniciar_gadget ..................................................................... 134 3.3.3.1.3.2. Configurar_gadget .............................................................. 135 3.3.3.1.3.3. Mostrar_repositorio............................................................ 137
iv
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.1.3.4. Cambiar_rama.................................................................... 139 3.3.3.1.3.5. Seleccionar_commit ........................................................... 140 3.3.3.1.3.6. Cambiar_pagina ................................................................. 141 3.3.3.1.3.7. Sincronizar ......................................................................... 142 3.3.3.1.3.8. Modificar_tamaño.............................................................. 143 3.3.3.2. Diseño .................................................................................................. 144 3.3.3.2.1. Diagrama de secuencia para “Iniciar gadget” .............................. 144 3.3.3.2.2. Diagrama de secuencia para “Configurar gadget” ....................... 145 3.3.3.2.3. Diagrama de secuencia para “Mostrar repositorio” ..................... 146 3.3.3.2.4. Diagrama de secuencia para “Cambiar rama” ............................. 147 3.3.3.2.5. Diagrama de secuencia para “Seleccionar commit” ..................... 148 3.3.3.2.6. Diagrama de secuencia para “Cambiar Página” ........................... 149 3.3.3.2.7. Diagrama de secuencia para “Sincronizar” .................................. 150 3.3.3.2.8. Diagrama de secuencia para “Modificar Tamaño” ....................... 151 3.3.3.3. Implementación ................................................................................... 151 3.3.3.3.1. Clases ......................................................................................... 151 3.3.3.3.2. Métodos por caso de uso ............................................................ 153 3.3.3.3.2.1. Iniciar_gadget .................................................................... 153 3.3.3.3.2.2. Configurar_gadget.............................................................. 156 3.3.3.3.2.3. Mostrar_repositorio ........................................................... 160 3.3.3.3.2.4. Cambiar_rama.................................................................... 163 3.3.3.3.2.5. Seleccionar_commit ........................................................... 164 3.3.3.3.2.6. Cambiar_página ................................................................. 165 3.3.3.3.2.7. Sincronizar ......................................................................... 166 3.3.3.3.2.8. Modificar_Tamaño ............................................................. 167 3.3.3.3.3. Template .................................................................................... 167 3.3.3.3.3.1. Propiedades ....................................................................... 169 3.3.3.3.3.2. Wiring ................................................................................ 170 3.3.3.3.3.3. Contexto ............................................................................ 171
v
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.3.3.4. Interfaz de usuario ...................................................................... 171
3.3.4. Github-browser ......................................................... 175 3.3.4.1. Interfaz de usuario ................................................................................ 175
4. Conclusiones .........................................................177 5. Líneas futuras .......................................................180 6. Glosario de términos .............................................181 7. Bibliografía ...........................................................184
vi
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
1. Introducción y objetivos 1.1. Presentación Se presenta en este documento la memoria del proyecto final de carrera “Desarrollo de gadgets integrados en la plataforma EzWeb, para visualizar repositorios „git‟ locales y hospedados en el servicio web”. En él, se espera que queden claro tres cosas. En primer lugar qué es lo propuesto a crear y cuál es cu cometido. En segundo lugar definir los conceptos que nos ayudarán a entender el marco en el cual transcurre el proyecto. Y por último, la parte técnica, el diseño y la implementación de la solución. Para rematar, se expondrán las conclusiones a las que se han llegado a través de la realización del mismo.
1.2. Objetivos Los objetivos del proyecto de forma descriptiva son los siguientes:
Desarrollar un conjunto de gadgets para la plataforma EzWeb que presenten repositorios git, tanto locales como albergados en el servicio web GitHub mediante una API REST. Desarrollar la API REST que adquiera la información (en local o en remoto) que hay que entregar a los gadgets. Presentar la información de los gadgets de una manera atractiva. Utilizar tecnologías web para todo el desarrollo. Integrar la solución con EzWeb para demostrar el potencial de esta plataforma.
1
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
1.3. Estructura del documento La documentación diferenciadas.
aquí
expuesta
se
divide
en
dos
partes
Por un lado vamos a describir todos los agentes que de alguna manera van a actuar con el sistema ya sea proporcionando soporte (como EzWeb) o proporcionando información (como GitHub) y todas las tecnologías empleadas en la realización del proyecto, el estado del arte. Por otra parte, describiremos cómo se ha afrontado la tarea en mano y cómo ha sido implementado (diseño e implementación). Además, se incluyen las conclusiones abstraídas de su realización. Pero antes de proseguir con el estado del arte, vamos a ver una visión general un poco más técnica de lo planteado y la solución aportada.
1.4. Visión general del proyecto Se plantea la realización de gadgets para la plataforma EzWeb con el propósito de visualizar repositorios git. Git es un software de control de versiones que se instala en máquinas Linux. Es por ello que para poder visualizar un repositorio, tendremos que poder acceder a él. Lo primero que se plantea es: ¿A qué repositorios Git vamos a acceder con los gadgets de EzWeb? EzWeb es un servicio web al que accedemos con un navegador, con lo cual el escenario básico de su uso es el que vemos en la siguiente figura (figura 1.1)
Figura 1.1 2
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Desde 2 (EzWeb Server) queremos poder acceder a repositorios git que estén instalados en cualquier máquina o en el servicio web github. Github es una web tipo red social (como facebook), pero de programadores, en la cual cada „perfil‟ tiene de forma pública el código de sus proyectos utilizando el repositorio git. Así pues la idea del proyecto es visualizar repositorios git desde el EzWeb Server, ya estén en el propio EzWeb Server, en otra máquina o en github, como podemos ver en la figura 1.2:
Figura 1.2
Para cumplir este cometido, se necesitarán dos cosas:
Primero un interfaz de usuario para mostrar la información de los repositorios en el navegador del usuario. Segundo algún método para acceder a esa información remota almacenada en los otros servidores y en gitub.
3
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Para el caso del interfaz, se utilizarán gadgets que funcionarán sobre la plataforma EzWeb, de qué forma se verá en la parte del estado del arte. El método para acceder a la información remota, será una API (o servicio web) que se tendrá que instalar en cada máquina que contenga un repositorio que queramos visualizar. A su vez, cada instalación de esta API tendrá la posibilidad de acceder a github para ver cualquier repositorio que esté hospedado allí. Por tanto, una visión general de la arquitectura del problema planteado es el de la figura 1.3
Figura 1.3
Para continuar, vamos a describir todas las tecnologías que tomarán partido en el desarrollo del proyecto.
4
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
2. Estado del arte 2.1. Plataformas de Mashup Por plataforma de mashup se entiende todo aquel entorno operacional, normalmente Web, que pueda combinar distintas fuentes de datos e integrarlas fácilmente en una sola. De esta manera se pueden obtener entornos avanzados, a partir de la composición de elementos más sencillos. Las plataformas de mashup se han hecho populares por su utilización en la sindicación de contenidos (RSS), sin embargo, no es su única aplicación. Su facilidad de uso, incluso por parte de usuarios inexpertos, y sus capacidades de composición e integración, los hacen especialmente atractivos de cara a obtener todo tipo de entornos operacionales avanzados altamente personalizables. Actualmente, existen diferentes soluciones software asociadas de algún modo al ámbito de los mashups. A pesar de que la variedad de estas soluciones es muy amplia, reciben de manera indiscriminada la denominación de plataformas de mashup. Sin embargo, es posible categorizar la mayoría de las plataformas basándonos en dos tipos bien diferenciados. Por un lado se puede encontrar, las plataformas de mashup de presentación. Se trata de plataformas que muestran una apariencia similar al escritorio de un sistema operativo, en las que el usuario incluye la información que desea, esta información suele proceder de diversas fuentes, y la distribuye libremente por el área de trabajo. De esta inclusión se obtiene una combinación de datos que aunque no llegan a mezclarse literalmente, sí se consigue un valor añadido para el usuario, ya que puede reunir en una misma ventana toda la información que desee. Por otro lado se tiene los mashups de datos, que se utilizan como su nombre indica, para combinar datos. Concretamente se mezclan
5
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
datos procedentes de más de una fuente distinta y se obtienen como resultado datos combinados y con un valor añadido con el que no contarían por separado. En definitiva, estas plataformas se han categorizado de este modo, atendiendo únicamente a su forma de manejar los datos. Por lo tanto, las plataformas de mashup se pueden clasificar atendiendo a dos criterios fundamentales:
Plataformas de mashup de presentación Plataformas de mashup de datos Estas dos categorías están ligadas entre sí pero, sin embargo, bien diferenciadas. A continuación se va a realizar una explicación de en qué consisten cada una de ellas.
2.1.1. Plataformas de Mashup de presentación En un mashup de presentación se realiza una mezcla de información procedente de diferentes fuentes mediante el uso de gadgets. Los gadgets son mini aplicaciones interactivas que pueden incorporarse dentro del “escritorio” del usuario. Estas mini aplicaciones pueden utilizarse por ejemplo para realizar un resumen de los últimos correos recibidos por el usuario, el tiempo de cualquier parte del mundo, las noticias de cualquier periódico electrónico del mundo o hasta una pequeña lista de tareas a realizar. Históricamente, la mayoría de estos gadgets han tenido como finalidad mostrar el contenido de algún tipo de sindicación Web, generalmente RSS. Sin embargo, la finalidad y complejidad de este tipo de gadgets no está especificado o restringido. De hecho, la mayoría de mashups de presentación dan la posibilidad de que el usuario cree sus propios gadgets, que por supuesto no tienen por qué limitarse a obtener datos de algún tipo de sindicación Web. La mayoría de los mashups de presentación tienen una apariencia similar a la del escritorio típico de los sistemas operativos tradicionales. Concretamente, los gadgets se incorporan a estos 6
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
escritorios virtuales y el usuario puede definir la posición y tamaño de los mismos. Este es el caso por ejemplo de NetVibes [net10] o iGoogle [igo10], que muestran escritorios virtuales que se alojan en un servidor Web y en los que el usuario puede definir los gadgets que se incluyen, así como ciertos aspectos de configuración como el aspecto o la posición. En definitiva se comportan exactamente igual que los gadgets para el escritorio de un sistema operativo, pero en este caso tanto los gadgets como el propio escritorio virtual se alojan dentro de un servicio que ofrece un tercero. Como se puede apreciar, este tipo de mashups realizan la composición de distintas fuentes para generar una nueva aplicación en la que el usuario decide toda la información que quiere que se muestre cada vez que acceda al escritorio sin necesidad de acceder a varias páginas Web distintas para obtener la misma información.
2.1.1.1. Gadget Fuera del mundo del software, un gadget es un dispositivo que tiene un propósito y una función específica, generalmente de pequeñas proporciones, práctico y a la vez novedoso. Los gadgets suelen tener un diseño ingenioso o fuera de lo común. El término gadget (frecuentemente conocido como widget), también se ha dado a una nueva categoría de mini aplicaciones o programas, usualmente presentados en archivos o ficheros pequeños. Entre sus objetivos están los de dar fácil acceso a funciones frecuentemente usadas y proveer de información visual. Sin embargo los gadgets pueden hacer todo lo que la imaginación desee e interactuar con servicios e información distribuida en Internet; pueden ser vistosos relojes en pantalla, notas, calculadoras, calendarios, agendas, juegos, ventanas con información del tiempo en su ciudad, etc. Un gadget, por tanto en el ámbito de los mashups, será un elemento software sencillo que puede ser incorporado a una plataforma de Mashup. Estos elementos pueden estar ligados a una o varias fuentes de 7
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
datos permitiendo la interacción con otros sistemas. Además, permiten llevar a cabo todo tipo de acciones: visualización de datos, intercambio de datos entre distintos gadgets, generación/recepción de datos, filtrado de datos, etc. Estas aplicaciones suelen estar diseñadas para proveer de información o mejorar una aplicación o servicios, o bien cualquier tipo de interacción a través de la Web; por ejemplo una extensión de alguna aplicación de negocios, que nos provea información en tiempo real del estatus del negocio u organización.
2.1.2. Plataformas de Mashup de Datos Los mashups de datos tienen un comportamiento muy distinto al de los mashups de presentación, aunque su finalidad también es la de obtener datos de distintas fuentes, combinarlos y generar datos nuevos. Generalmente, este tipo de mashups puede obtener sus datos de terceros de formas muy diversas. Aunque típicamente lo hacen a través de la sindicación Web, el Screen Scrapping o a través de la utilización de la API de otro servicio. Si el número y variedad de fuentes de que se disponga a la hora de hacer los mashups es importante, más aún lo es si cabe, el tipo de datos que se pueden manejar. Los tipos de datos también pueden ser muy variados y al igual que las fuentes dependen de la plataforma en la que el usuario se encuentre. El tipo de datos más habitual suele ser XML [BPSM+ 00], pero otros formatos como RSS, Atom, JSON [Cro06], e incluso la API concreta de algún otro servicio también pueden estar disponibles. El aspecto más importante de un mashup de datos es sin lugar a dudas, la definición de las operaciones que se pueden realizar sobre los datos de entrada para crear los nuevos datos enriquecidos. En este sentido, los operadores más comunes dentro de estas plataformas de mashup suelen ser el filtrado, los bucles o iteraciones, selectores y los splits de datos. En cualquier caso, el número de
8
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
operadores y el tipo de los mismos es un aspecto más difícil de abarcar que los tipos de datos de entrada y salida de estos mashups principalmente porque el abanico de opciones disponibles es mucho mayor. Por último, el tercer aspecto importante son los tipos de datos que produce el mashup. Con estos ocurre lo mismo que con los tipos de entrada, es decir, la variedad de los mismos depende de la plataforma con la que trabaje. Sin embargo, sí que se puede decir que los formatos predominantes son XML, o en su defecto RSS que es un subconjunto del lenguaje XML destinado a la sindicación Web. Es muy importante destacar que este tipo de mashups cuya finalidad es la de generar datos concretos a partir de datos de entrada de más de una fuente distinta, tienen muchas posibilidades de ser convertidos posteriormente en gadgets para los mashups de presentación. Concretamente, la utilización conjunta de estos dos tipos de mashups puede generar aplicaciones complejas y muy completas. De hecho, la gran potencia de los mashups reside precisamente en la utilización conjunta de estos dos tipos de enfoque, por un lado los mashups de datos que ayudan a crear nuevos gadgets que obtienen sus datos a partir de la combinación de más de una fuente distinta, y por otro lado, los mashups de presentación que ayudan a combinar varios gadgets dentro de un mismo ”escritorio”, con lo que se puede obtener una aplicación conjunta mucho más potente y versátil. Si a estas posibilidades que ofrecen los mashups de presentación con la incorporación más o menos libre de los gadgets, se le añade la posibilidad de comunicación entre los mismos, se puede lograr una aplicación que se asemeje mucho a las posibilidades de cualquier aplicación típica de escritorio, con la ventaja de que ésta, al estar alojada en un servidor Web, estaría disponible en cualquier parte del mundo siempre que se disponga de conexión a Internet y de un navegador Web, sin la necesidad de instalar ningún tipo de software ni de ninguna configuración adicional.
9
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
2.1.3. EzWeb, plataforma de Mashup empresarial El proyecto EzWeb se centra en el desarrollo de tecnologías clave a emplear en el desarrollo de la capa de acceso web (front-end layer) a los servicios sobre Arquitecturas Orientadas a Servicios (SOA – Service Oriented Architecture) de nueva generación que permitan dar soporte a los siguientes aspectos:
Los usuarios finales deben contar con la máxima autonomía y capacidad de personalización en relación con la configuración de su entorno operativo, como resultado de localizar, elegir, personalizar y combinar de manera flexible y dinámica (siguiendo un modelo de autoservicio o filosofía tipo IKEA) recursos disponibles en la red.
Los usuarios finales deben contar con la capacidad de crear y compartir conocimiento, que se materialice en la capacidad de construir nuevos recursos y publicarlos en la red, así como intercambiar experiencias con otros, aprendiendo juntos y acelerando de este modo tanto la incorporación constante de innovaciones como la mejora de la productividad.
La interacción debe adaptarse y ser relevante al contexto, dando al término “contexto” el significado más amplio posible, de manera que comprenda elementos tales como el contexto del usuario (conocimiento, perfil, preferencias, idiomas, información sobre las redes sociales a las que el usuario pertenece, etc.) o el contexto de utilización (características estáticas y dinámicas del dispositivo usado para el acceso, localización geográfica y de tiempo, la conexión de banda ancha, etc.); y teniendo en cuenta tanto la variabilidad del contexto como la movilidad de los usuarios.
10
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
EzWeb plantea su evolución dentro de las siguientes líneas de actividad:
Gestión avanzada del entorno operativo. Catálogo de Recursos. Marketplace de Recursos. Técnicas de adquisición y explotación del conocimiento. Entorno de Desarrollo Avanzado. La plataforma EzWeb propone un mecanismo de intercomunicación altamente flexible, que permite a los gadgets adaptarse a las capacidades cambiantes y en constante evolución de la plataforma, sin necesidad de reprogramar el código de los gadgets. Para conseguir esto se ha implementado un mecanismo basado en la utilización de flujos de datos genéricos, que son ligados dinámicamente a aspectos implementados dentro de la plataforma. Estos aspectos representan el conjunto de funcionalida des cruzadas (cross-cutting), que la plataforma expone para ser utilizadas y dar soporte al desarrollo de los gadgets. Actualmente se dispone de los siguientes aspectos:
Propiedad: Permite el almacenamiento persistente. Evento: Habilita la gestión de la publicación de eventos. Ranura: Habilita la gestión de la suscripción a eventos. Preferencia: Habilita la gestión de la interfaz de configuración de usuario. Contexto: Permite acceder a información del delivery-context (de usuario, plataforma o gadget). La inclusión de estos aspectos, desde el punto de vista de los programadores, dentro del código de los gadgets es simple. El programador puede definir flujos de datos: bien de sólo lectura, bien de lectura y escritura, mediante una clase que presenta una interfaz basada en un getter, un setter y una función de callback a invocar por el sistema, a modo de manejador, cuando el valor de
11
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
un flujo concreto se ve modificado desde el exterior. A este nivel el programador sólo necesita trabajar con estos conceptos, flujos de entrada (lectura) y flujos de entrada y salida (lectura/escritura). Estos flujos constituyen el punto de ligadura (Jointpoint) con los aspectos (Figura 2.1).
Figura 2.1 La siguiente fase, meramente declarativa, permite asignar a cada uno de estos flujos genéricos los aspectos funcionales que regirán su comportamiento. Esta especialización se realiza en el Template asociado a cada gadget (Información declarativa asociada al despliegue de un gadget). Dependiendo del tipo del flujo se permiten diferentes asignaciones de aspectos, así los Eventos, las Propiedades se consideran aspectos de
12
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
lectura/escritura, y las Ranuras, las Preferencias de usuario, el Contexto serán de sólo lectura. Una característica importante a tener en cuenta es que todos los aspectos de lectura/escritura son intercambiables entre sí, lo mismo ocurre con los de sólo lectura. Es decir un Slot puede ser transformado en Preferencia o un Evento en Propiedad de forma dinámica. De este modo se proporciona un entorno que permite a los Gadgets adaptarse de forma altamente flexible a las nuevas capacidades que puedan aparecer en la plataforma de mashup, sin necesidad de cambiar su implementación. Gracias a su simplicidad el mecanismo desarrollado minimiza el acoplamiento entre el código del gadget y las funcionalidades de la plataforma potenciando su utilización por parte de todo tipo de desarrollos no pensados inicialmente para su despliegue en EzWeb. 2.1.3.1. Estructura de EzWeb La funcionalidad de la Plataforma EzWeb se distribuye en tres módulos principales: Workspace, Catalogue y Wirings. En EzWeb se permite cambiar el idioma por defecto de la plataforma así como el de salida de la sesión actual o logout.
Figura 2.2 13
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
El Workspace (figura 2.2) se corresponde con el entorno operacional del usuario. Es aquí donde el usuario puede agregar los gadgets que compondrán su propia interfaz con el sistema. La plataforma ofrece una gran flexibilidad a la hora de ubicar los gadgets en el entorno operacional. Se puede modificar su distribución libremente en busca de una mayor optimización del espacio. Los desarrolladores además pueden definir propiedades para cada gadget pudiendo ser visualizadas y modificadas en la barra superior de cada gadget.
Figura 2.3 En el Catálogo (figura 2.3) se muestran todos los gadgets disponibles de la plataforma que pueden agregarse al entorno operacional. Cada gadget en el catálogo aparece en un recuadro individual junto con una imagen descriptiva y el correspondiente botón para añadir el gadget al entorno operacional. Desde estos recuadros puede accederse a toda la información relativa al gadget. En la parte superior de cada gadget dispone de una barra con tres botones (aparecen al desplazar el cursor sobre ella) con los cuales se permite acceder a la siguiente información:
14
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Una breve descripción del gadget (D). La entrada a una wiki con una descripción más extensa del gadget (W). El template correspondiente (T).
Además en el catálogo si se pulsa sobre un gadget se podrán consultar toda la información relativa al gadget se proporciona información relevante como:
Valoración por parte de los usuarios. Etiquetas que le han sido asignadas al gadget para su identificación en la plataforma. Variables Events y Slots de cada gadget. Enlace a la documentación sobre el desarrollo y/o guía de uso del gadget.
La plataforma proporciona un mecanismo rápido para añadir nuevos gadgets al catálogo desde cualquier parte en Internet. Para ello la plataforma tiene una guía para el desarrollo de gadgets en la que son explicadas las pautas que deben seguirse en el desarrollo de cada gadget para ser integrados en la plataforma de mashups.
Figura 2.4 15
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
En el módulo Wiring (figura 2.4) reside una de las características que distingue a la plataforma EzWeb. Como ya se ha comentado, se ofrece la posibilidad de establecer conexiones entre los distintos gadgets instanciados en el entorno operacional. Estas conexiones se basan en canales de información, de manera que un canal se asocia a un dato (dirección de usuario, modelo de coche seleccionado, etc.) y nunca a los propios gadgets. Los canales utilizan las variables de tipo Event y Slot de los gadgets como entrada y salida de datos, respectivamente para posibilitar la conexión entre los mismos.
2.2. Repositorios de código Una versión, revisión o edición de un producto, es el estado en el que se encuentra dicho producto en un momento dado de su desarrollo o modificación. Se llama control de versiones (repositorio) a la gestión de los diversos cambios que se realizan sobre los elementos de algún producto o una configuración del mismo. Los sistemas de control de versiones facilitan la administración de las distintas versiones de cada producto desarrollado, así como las posibles especializaciones realizadas (por ejemplo, para algún cliente específico). El control de versiones se realiza principalmente en la industria informática para controlar las distintas versiones del código fuente. Sin embargo, los mismos conceptos son aplicables a otros ámbitos como documentos, imágenes, sitios web, etcétera.
2.2.1. Git Git es un software de sistema de control de versiones diseñado por Linus Torvalds, pensando en la eficiencia y la confiabilidad del mantenimiento de versiones de aplicaciones cuando estas tienen un gran número archivos de código fuente. Al principio, Git se pensó como un motor de bajo nivel sobre el cual otros pudieran escribir el interfaz de usuario o front. Sin embargo, Git se ha convertido desde entonces en un 16
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
sistema de control de versiones con funcionalidad plena. Hay algunos proyectos de mucha relevancia que ya usan Git, en particular, el grupo de programación del núcleo del sistema operativo GNU/Linux. El diseño de Git resulta de la experiencia del diseñador de Linux, Linus Torvalds, manteniendo una enorme cantidad de código distribuida y gestionada por mucha gente, que incide en numerosos detalles de rendimiento, y de la necesidad de rapidez en una primera implementación. Entre las características más relevantes se encuentran: Fuerte apoyo al desarrollo no-lineal, por ende rapidez en la gestión de ramificaciones y mezclado de diferentes versiones. Git incluye herramientas específicas para navegar y visualizar un historial de desarrollo no-lineal. Una presunción medular en Git es que un cambio será fusionado o empalmado mucho más frecuentemente de lo que se escribe originalmente, conforme se pasa entre varios programadores que lo revisan. Gestión distribuida. Al igual que Darcs, BitKeeper, Mercurial, SVK, Bazaar y Monotone, Git le da a cada programador una copia local del historial del desarrollo entero, y los cambios se propagan entre los repositorios locales. Los cambios se importan como ramificaciones adicionales y pueden ser fusionados en la misma manera que se hace con la ramificación local. Los almacenes de información pueden publicarse por HTTP, FTP, rsync o mediante un protocolo nativo, ya sea a través de una conexión TCP/IP simple o a través de cifrado SSH. Git también puede emular servidores CVS, lo que habilita el uso de clientes CVS pre-existentes y modulos IDE para CVS pre-existentes en el acceso de repositorios Git. Los repositorios Subversion y svk se pueden usar directamente con git-svn. Gestión eficiente de proyectos grandes, dada la rapidez de gestión de diferencias entre archivos, entre otras mejoras de optimización de velocidad de ejecución.
17
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Todas las versiones previas a un cambio determinado, implican la notificación de un cambio posterior en cualquiera de ellas a ese cambio (denominado autenticación criptográfica de historial). Esto existía en Monotone. Resulta algo más caro trabajar con ficheros concretos frente a proyectos, eso diferencia el trabajo frente a CVS, que trabaja con base en cambios de fichero, pero mejora el trabajo con afectaciones de código que concurren en operaciones similares en varios archivos. Los renombrados se trabajan basándose en similitudes entre ficheros, aparte de nombres de ficheros, pero no se hacen marcas explícitas de cambios de nombre con base en supuestos nombres únicos de nodos de sistema de ficheros, lo que evita posibles, y posiblemente desastrosas, coincidencias de ficheros diferentes en un único nombre. Realmacenamiento periódico en paquetes (ficheros). Esto es relativamente eficiente para escritura de cambios y relativamente ineficiente para lectura si el reempaquetado (con base en diferencias) no ocurre cada cierto tiempo.
2.2.2. Github Github es un servicio de hosting basado en Web para proyectos que utilizan el sistema de revisión de código Git. Escrito en Ruby on Rails, ofrece planes comerciales y gratuitos para proyectos de tipo opensource (código libre). Acorde al análisis de usuarios Git de 2009, Github es el servicio de hosting más popular. El servicio, proporciona funiconalidades de redes sociales, como feed de noticias, seguidores y gráficos de todo tipo para mostrar como un usuario (desarrollador) trabaja en los proyectos que tenga allí hospedados.
18
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
2.3. Tecnologías Describimos en esta sección las tecnologías empleadas en la realización del proyecto. Todas ellas están relacionadas con las nuevas tecnologías web.
2.3.1. Javascript Javascript es un lenguaje de scripting1 orientado a objetos2 que se utiliza para acceder a objetos del programa que lo ejecuta y de otros programas. Su principal uso es como componente de un navegador, permitiendo el desarrollo de mejores interfaces de usuario y páginas web dinámicas3. Como su nombre indica, fue diseñado para que se pareciese a Java4, pero con una sintáxis de fácil aproximación para todo aquel que no estuviera acostumbrado a programar. En el proyecto, javascript se ha utilizado para desarrollar la lógica de los gadgets, es decir, su funcionalidad interna. Como hemos visto antes en el escenario cliente-servidor, javascript se ejecuta en cliente (en el navegador).
2.3.2. HTML Hyper Text Marking Language (Lenguage de marcado de hipertexto) es la tecnología principal empleada en el desarrollo de
1
Lenguaje de programación que permite el control de otros programas software. A diferencia de estos, es interpretado en tiempo de ejecución, no compilado previamente 2
Paradigma de programación cuya estructura de datos fundamental son los “objetos”, Paradigma de programación cuya estructura de datos fundamental son los “objetos”, un conjunto de variables y funciones para manipularlos que suelen abstraer al mundo real 2
3
Una web dinámica, es aquella que cambia de aspecto o de información, sin necesidad de actualizar la página o acceder a un enlace. 4
Lenguaje de programación orientado a objetos de alto nivel.
19
Mario Mira Boronat
páginas web estructuras.
[PROYECTO FINAL DE CARRERA]
estructuradas,
dotando
de
semántica
a
estas
Básicamente un documento HTML consta de una cabecera y un cuerpo. En la cabecera se aporta información descriptiva del documento que concierne al navegador, como por ejemplo otros ficheros empleados (como pueden ser scripts de JavaScript) o el juego de caracteres empleado. En el cuerpo del documento, se incorporan textos, imágenes, vídeos… todo tipo de información. En nuestro caso, cada gadget tendrá un documento HTML asociado, que hará las veces de contenedor para presentar los datos.
2.3.4. CSS Las hojas de estilo en cascada (en inglés Cascading Style Sheets), CSS es un lenguaje usado para definir la presentación de un documento estructurado escrito en HTML o XML (y por extensión en XHTML). El W3C (World Wide Web Consortium) es el encargado de formular la especificación de las hojas de estilo que servirán de estándar para los agentes de usuario o navegadores. CSS proporciona tres caminos diferentes para aplicar las reglas de estilo a una página Web:
Una hoja de estilo externa, que es una hoja de estilo que está almacenada en un archivo diferente al archivo donde se almacena el código HTML de la página Web. Esta es la manera de programar más potente, porque separa completamente las reglas de formateo para la página HTML de la estructura básica de la página.
Una hoja de estilo interna, que es una hoja de estilo que está incrustada dentro de un documento HTML. (Va a la derecha dentro del elemento <head>). De esta manera se obtiene el beneficio de
20
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
separar la información del estilo, del código HTML propiamente dicho. Se puede optar por copiar la hoja de estilo incrustada de una página a otra, (esta posibilidad es difícil de ejecutar si se desea para guardar las copias sincronizadas). En general, la única vez que se usa una hoja de estilo interna, es cuando se quiere proporcionar alguna característica a una página Web en un simple fichero, por ejemplo, si se está enviando algo a la página web.
Un estilo en línea, que es un método para insertar el lenguaje de estilo de página, directamente, dentro de una etiqueta HTML. Esta manera de proceder no es totalmente adecuada. El incrustar la descripción del formateo dentro del documento de la página Web, a nivel de código se convierte en una tarea larga, tediosa y poco elegante de resolver el problema de la programación de la página. Este modo de trabajo se podría usar de manera ocasional si se pretende aplicar un formateo con prisa, al vuelo. No es todo lo claro, o estructurado, que debería ser, pero funciona.
2.3.5. Python Es un lenguaje de programación de alto nivel de propósito general cuyo diseño se centra en la facilidad para leer el código generado con él. Dado que está basado en C, es muy eficiente y además es un híbrido entre lenguaje de scripting y lenguaje convencional, ya que la primera vez que de ejecuta un programa en python, se ejecuta como script a la vez que se compila para una mayor eficiencia en futuras ejecuciones. Soporta los principales paradigmas de programación: objetos, estructurado y funcional, además de dejar hueco para futuros paradigmas.
21
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Al ser tan potente, tiene una gran variedad de usos, pero el que nos interesa es su capacidad para realizar tareas en el lado servidor de las aplicaciones web. Concretamente, vamos a utilizar Python para programar una API REST en forma de App para Django, que nos permitirá obtener a través de la Web la información de los repositorios git locales y de GitHub. De esta forma el código python comprenderá la parte servidora de la solución.
2.3.6. JSON JSON, short for JavaScript Object Notation, is a lightweight computer data interchange format. It is a text-based, humanreadable format for representing simple data structures and associative arrays (called objects). Javascript Object Notation (Notación de objetos javascript) es un formato ligero de intercambio de datos entre ordenadores. Está basado en texto y su formato es legible por el ser humano para representar estructuras de datos simples. Es decir, JSON se encarga de generar una cadena de texto estandarizada para intercambiar información entre ordenadores. En su uso más común, estos ordenadores están comunicados a través de internet a modo de cliente-servidor. Para el proyecto, JSON va a ser el estándar de comunicación que vamos a emplear para los canales de información empleados. Estos son el canal Gadgets-API Django y el canal API Django – Web Github, como veremos más adelante. XML (Extensible Markup Language): Son un conjunto de reglas para estructurar documentos electrónicos. Es similar al HTML en la forma de poner las marcas, con la diferencia de que dichas marcas pueden representar lo que queramos.
22
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Cada marca, dota de significado semántico al texto que le acompaña. Gracias a esta flexibilidad, XML se ha convertido en uno de los principales estándares para compartir información de forma electrónica. Hoy día, su uso es muy variado, desde una forma estándar para almacenar documentos Office (como Word, OpenOffice…), hasta una manera común de transmitir información como noticias (RSS, ATOM…). Para nuestro propósito, XML va a definir las propiedades de los gadgets que creemos, según la forma predefinida que decidieron en su día los creadores de la plataforma EzWeb. SOAP (Simple Object Access (Representational State Transfer):
Protocol)
o
REST
Protocolos sobre los que se establece el intercambio de recursos. Vamos a ver REST en más detalle en el siguiente punto.
2.3.7. REST REST, del inglés Representational State Transfer, y ya traducido al castellano como la transferencia de Estado Representacional es una técnica de arquitectura para sistemas hipermedia distribuidos como la WorldWide Web. El término fue introducido en el año 2000, en una tesis doctoral sobre la Web escrita por Roy Fielding [Fie], uno de los principales autores de la especificación del protocolo HTTP y ha pasado a ser ampliamente utilizado por la comunidad de desarrolladores. Si bien el término REST se refería originariamente a un conjunto de principios de arquitectura (descritos más adelante), en la actualidad se usa en el sentido más amplio para describir cualquier interfaz Web simple que utiliza XML y HTTP sin las abstracciones adicionales de los protocolos basados en patrones de intercambio de mensajes como el protocolo de servicios Web SOAP Es posible diseñar sistemas de servicios Web de acuerdo con el estilo
23
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
arquitectural REST de Fielding y también es posible diseñar interfaces XMLHTTP de acuerdo con el estilo de llamada a procedimiento remoto pero sin usar SOAP. Estos dos usos diferentes del término REST causan cierta confusión en las discusiones técnicas, aunque RPC no es un ejemplo de REST. Los sistemas que siguen los principios de REST se llaman con frecuencia RESTfull. Los defensores más acérrimos de REST se llaman a sí mismos RESTafaris. REST afirma que la Web ha disfrutado de escalabilidad como resultado de una serie de diseños fundamentales clave: Un protocolo cliente/servidor sin estado: cada mensaje HTTP contiene toda la información necesaria para comprender la petición. Como resultado, ni el cliente ni el servidor necesitan ningún estado de las comunicaciones entre mensajes. Sin embargo, en la práctica muchas aplicaciones basadas en HTTP utilizan cookies y otros mecanismos para mantener el estado de la sesión (algunas de estas prácticas, como la reescritura de URLs, no son permitidas por REST). Un conjunto de operaciones bien definidas que se aplican a todos los recursos de información: HTTP en sí define un conjunto pequeño de operaciones, las más importantes son POST, GET, PUT y DELETE. Con frecuencia estas operaciones se equiparan a las operaciones CRUD que se requieren para la persistencia de datos, aunque POST no encaja exactamente en este esquema. Una sintaxis universal para identificar los recursos. En un sistema REST, cada recurso es direccionable únicamente a través de su URI. El uso de hipermedios, tanto para la información de la aplicación como para las transmisiones de estado de la aplicación: la representación de este estado en un sistema REST son típicamente HTML o XML. Como resultado de esto, es posible navegar de un recurso REST a muchos otros, simplemente siguiendo enlaces sin requerir el uso de registros u otra estructura adicional.
24
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
2.3.8. El Framework Django Django es un framework de desarrollo web de código abierto, escrito en Python, que cumple en cierta medida el paradigma del Modelo Vista Controlador. Fue desarrollado en origen para gestionar varias páginas orientadas a noticias de la World Company de Lawrence, Kansas, y fue liberada al público bajo una licencia BSD en julio de 2005. La meta fundamental de Django es facilitar la creación de sitios web complejos. Django pone énfasis en el re-uso, la conectividad y extensibilidad de componentes, del desarrollo rápido y del principio de DRY (del inglés Don‟t Repeat Yourself). Python es usado en todas las partes del framework, incluso en configuraciones, archivos, y en los modelos de datos.
2.3.8.1. Django Apps Sobre Django se programan las denominadas “Django Apps”. Estsa son pequeñas o grandes aplicaciones que funcionan únicamente sobre este Framework. Para el desarrollo del proyecto, se ha programado una App para Django que hace las veces de API de los gadgets. El entorno EzWeb se nutre de muchas de estas webs para su funcionamiento, con lo que la integración de la solución con EzWeb, es sencilla, ya que bastaría con instalar una App nueva al entorno.
25
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3. Diseño e implementación Vista ya la sección del estado del arte y la introducción, se procede a presentar el desarrollo de la solución. Para ello, esta parte se divide en tres segmentos. Uno inicial, en el que se verá una visión global de la solución, para que se pueda asentar el marco sobre el que se va a trabajar y posteriormente se hará hincapié en los dos grandes pilares del desarrollo, el adaptador (API) y los gadgets. En la primera parte se explicará porqué ha sido necesario introducir una API a la solución, así como el número de gadgets que forman parte de ella. En la segunda, se abordará la API implementada y por último, en la tercera se verá cada gadget de forma separada para detallar su diseño e implementación.
3.1. Visión general de la solución El proyecto desarrollado se encarga de visualizar repositorios git albergados tanto en una máquina cualquiera como en el servicio web GitHub. La restricción inicial impuesta es que se debe desarrollar mediante gadgets para la plataforma EzWeb. Debido a que en dicha plataforma no se ofrecen servicios para acceder al disco duro de la propia máquina que ofrece la plataforma EzWeb, ni al disco duro de otras máquinas que contengan reposiotirios git, se ha decidido implementar una capa intermedia entre los gadgets y los repositorios. Esta capa intermedia, se ha propuesto como una API REST utilizando el framework Django. El motivo de utilizar dicho framework es variado, en primer lugar ofrece bastante sencillez en la programación de este tipo de API‟s, en segundo lugar, la propia plataforma EzWeb 26
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
también lo utiliza, con lo que de tener que ser implantada en la misma máquina que sirve la plataforma, sería fácil su integración. Por último, el framework Django utiliza el lenguaje de programación Python, que nos ofrece, como veremos más adelante, una serie de librerías que se utilizan para facilitar el acceso a los repositorios git, tanto locales como remotos (GitHub).
Cabe destacar, que sería posible programar directamente el acceso a los repositorios GitHub desde los gadgets de la plataforma EzWeb. No obstante, para aumentar la coherencia de la solución, se ha optado por dejarle a la API la responsabilidad de proporcionar la información de los repositorios tanto locales como remotos a los gadgets.
Con estas restricciones en mente, se presenta el modelo de comunicaciones empleado.
Figura 3.1 Como se aprecia en la figura 3.1, hay 4 actores en lo que a comunicaciones se refiere: 1- Browser: Es el ordenador del usuario, que lo único que necesita para funcionar con el sistema es un navegador.
27
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
2- EzWeb Server: Es el servidor dónde está instalada la plataforma EzWeb, será aquí donde se instalen los gadgets desarrollados en la solución del proyecto. 3- Django Server: En este servidor se implementará la API (el servicio encargado de contestar las peticiones de los gadgets). Esta API tendrá dos modos de operación, uno local, en el que buscará datos en el propio servidor; y otro remoto, en el que pedirá los datos al servicio web GitHub. 4- GitHub: Se trata del servicio web GitHub, que podemos encontrar en www.github.com; Este servicio, posee su propia API que contestará a las peticiones de la desarrollada para mostrar la información en el navegador del usuario. Apreciamos también varios canales de comunicación (A,B,C,D,E): A) Browser-EzWeb: Este canal de comunicación no es competencia de la solución, es propio de EzWeb, y es el encargado de enviar al navegador del usuario el “workspace” de EzWeb, el entorno en el que funcionan los gadgets. B) EzWeb-API: A diferencia de “A”, este canal de comunicación es desarrollado en su totalidad por la solución propuesta y es el encargado de realizar las peticiones de información que hace el usuario mediante los gadgets y su correspondiente respuesta.
C) API-API: Este canal representa el escenario en el que los datos que solicitan los gadgets se correspondan con repositorios git instalados en el propio servidor Django que contiene la API. Si esta es la información pedida, no es necesario acceder a GitHub y la API accede a los datos necesarios en local.
D) API-Github: En este caso, los datos solicitados están almacenados en el servicio web GitHub, con lo que la API
28
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
desarrollada deberá comunicarse con dicho servicio para obtener los datos requeridos a través de internet. E) Browser-Github: El último canal a describir es un caso especial. Como veremos más adelante, se ha desarrollado un gadget extra por mejorar la usabilidad del sistema, que permite navegar por los repositorios y los usuarios hospedados en el servicio GitHub. Para cumplir este cometido y que se pueda utilizar el gadget de forma independiente al sistema, en vez de realizar peticiones a la API Django, se realizan peticiones directamente a GitHub a través de internet con la propia API que proporciona EzWeb. Una vez explicada esta visión global de las comunicaciones del sistema, ahora vamos a describir qué tecnologías toman partido en cada uno de sus actores (Figura 3.2).
29
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Figura 3.2 1 – Browser: En el navegador del usuario se ejecuta la plataforma EzWeb, en ella, el usuario va a manejar los gadgets. Cada gadget está programado con HTML, Javascript, CSS y XML. XML y HTML sirven para describir el contenedor del gadget y sus propiedades. JavaScript se va a encargar de la lógica del gadget, es decir, su comportamiento. Por último CSS es el encargado de darle apariencia al gadget. Este navegador, se comunica el servidor “2”, que es el que hospeda EzWeb y le sirve la plataforma y sus gadgets mediante el protocolo estándar web HTTP.
30
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
2 – EzWeb Server: EzWeb es una plataforma web que está programada sobre el framework Django. Este framework está desarrollado íntegramente en el lenguaje python y se ayuda de una base de datos para almacenar toda la información persistente entre sesiones. En nuestro caso, hemos reflejado el gestor de base de datos MySQL, no obstante Django puede funcionar con otros gestores de base de datos como por ejemplo postgreSQL. Toda esta parte del diagrama es desarrollada por el proyecto Morpheo, por lo que no forma parte de la solución desarrolada. Los gadgets que se ejecutan en esta plafaroma, sí. La comunicación entre el servidor de EzWeb (2) y el Servidor Django (3) que sí ha sido desarrollado por el alumno, se realiza mediante peticiones estándar HTTP. Las respuestas a estas peticiones (que contienen la información a mostrar en los gadgets) utilizan el estándar JSON.
3 – Django Server: Al igual que la plataforma EzWeb, el servidor que contiene la API que resuelve las peticiones de información de los gadgets, está programado sobre el framework Django en el lenguaje python. Tanto para los accesos locales como para los accesos a través de internet a GitHub, se han utilizado liberías externas de python, que nos ayudarán a “parsear5” los datos de los repositorios. No obstante, en este caso, no es necesario el uso de un gestor de base de datos, ya que la API no guardar información para futuras sesiones. En el caso del diálogo entre la API de Django programada en python y el servidor de GitHub (internet), se utilizan los mismos protocolos que entre los gadgets y EzWeb, HTTP para la comunicación y JSON para el formato de la respuesta. Cabe destacar, que el servicio GitHub, da la opción de recibir las respuestas de su API tanto en JSON como en YAML. Se ha elegido pedirle las respuestas JSON por coherencia con las que envía la propia API. De las peticiones locales a
5
Un “parser” es un programa que lee unos datos de entrada y los transforma en algo útil y procesado. En nuestro caso, las librerías nos transforman los datos de los repositorios en un formato de fácil manejo.
31
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
los repositorios git se va a encargar el propio sistema operativo de la máquina, al ser un acceso normal a su disco duro. 4 – GitHub: El web service de GitHub contiene una API que nos da acceso a todos los datos que un usuario normal podría acceder navegando por su web.
32
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Llegados a este punto se tiene una visión global del problema planteado y la solución aportada a nivel comunicativo y tecnológico, sólo nos queda ver para tener la visión completa, cómo son los gadgets desarrollados y una breve descripción de su funcionamiento.
La solución final consta de 4 gadgets:
Figura 3.3 Git-file (figura 3.3): Es el gadget de menor nivel de abstracción del conjunto, su trabajo es sencillo, se encarga de mostrar el contenido de cualquier fichero de código seleccionado del repositorio. Para ello,
33
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
muestra el nombre del fichero en su cabecera (1), y en el cuerpo (2) el contenido del mismo. Para desarrollar este gadget, se ha utilizado una libería (EditArea6) javascript que nos formatea el texto del fichero para resaltar su semántica (según la extensión del fichero), nos adhiere a la izquierda el número de línea y nos proporciona funcionalidades de cambiar el tamaño de letra de la fuente y buscar cadenas de texto en el contenido.
Figura 3.4
Git-tree (figura 3.4): Este gadget es el encargado de mostrar el árbol de ficheros que está relacionado con cada “commit”7 del repositorio. Para esta labor se ha modificado una librería externa
6
http://www.cdolivet.com/index.php?page=editArea
7
Un commit, es una “fotografía” del estado de un proyecto. Guarda todos los ficheros que hay en ese momento y su contenido. Se le asocia siempre un árbol de ficheros que conforman dicha fotografía.
34
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
dtree8. En su cabecera (1) se muestra el hash del árbol en el repositorio (formato SHA19) que es el único elemento que nos proporciona el repositorio git para discernir entre un árbol u otro. En el cuerpo (2) se muestran los ficheros y directorios que componen el árbol. Si hacemos click en un fichero, este se transmite a git-file para mostrar su contenido; y si por el contrario, hacemos click en un directorio, este se despliega mostrando a su vez los ficheros y directorios que contenga.
Figura 3.5 Git-commits: Es el gadget principal del conjunto. Cumple dos funciones (A) y (B), la primera (A) es la configuración de los anteriores (figura 3.5) (git-file y git-tree) en la que se le da la información sobre la ubicación de la API que accede a los datos (1), el tipo de acceso que queremos realizar (2) (local o a github) y, dependiendo de dicho acceso,
8
http://destroydrop.com/javascripts/tree/
9
SHA1 es insertar descripción
35
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
los parámetros sobre a qué repositorio queremos acceder (3) para local y (4) para github.
Figura 3.6 Su segunda funcionalidad (B) es mostrarnos un repositorio git (figura 3.6), ya sea local o remoto. Para ello nos presenta distintos tipos de información: (5) El nombre del repositorio y su tipo de acceso, (6) la rama (branch) del repositorio, (7) la lista de los commits más recientes con la opción de paginar para ver más (8) y (9) la información asociada a cada commit. Cada vez que hacemos click en un commit, el gadget se encarga de enviarle a git-tree la cadena SHA1 del árbol asociado a ese commit para que lo muestre.
36
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Figura 3.7 Github-browser (figura 3.7): El último gadget del conjunto, no forma parte de la solución al problema, ya que con los otros 3 se satisfacen los requisitos. No obstante, se decidió desarrollar porque mejoraba de forma significativa el uso de todo el sistema. Es un buscador del servicio web GitHub. Con él, podemos buscar repositorios albergados en este servicio según dos criterios: Nombre de usuario (A) o nombre del repositorio (B). De esta manera, si queremos por ejemplo ver la lista de repositorios del usuario “test”, podemos buscar (1) repositorios con nombre de usuario “test”. Del listado que nos aparecerá (2) podemos seleccionar cualquier repositorio y se le enviará el nombre de usuario y nombre del repositorio al gadget gitcommits para que muestre su información y a su vez configure a gittree y git-file.
37
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Cabe destacar que la funcionalidad principal del sistema EzWeb es precisamente la habilidad de comunicar gadgets entre sí, es por ello que se ha puesto énfasis en separar el sistema en el mayor número de componentes posible, para que otros gadgets desarrollados por futuros programadores, puedan conectarse a estos y recoger los datos que proporcionan. Descrito este último punto, ya se conoce la visión total del problema propuesto y solución planteada, ahora se procede a explicar en detalle cada uno de los componentes (gadgets) y la API desarrollada.
3.2. Adaptador (API) 3.2.1. Especificación Los requisitos identificados para el diseño del adaptador del sistema (API) son los siguientes:
REQ. 1: El adaptador debe permitir consultas a repositorios git locales. REQ. 2: El adaptador debe permitir consultas a repositorios git hospedados en GitHub
Para mejorar la seguridad del sistema se añade el siguiente requisito:
REQ. 3: El adaptador debe proporcionar algún mecanismo para validar que la URL es correcta.
Basándonos en estas premisas, se extienden los requisitos según la información que queramos obtener:
A partir del REQ. 1, consultas locales:
38
REQ. 1.1: El adaptador debe permitir consultar el listado de repositorios locales disponibles REQ. 1.2: El adaptador debe permitir consultar las ramas (branches) de un repositorio local.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
REQ. 1.3: El adaptador debe permitir consultar la lista de commits de un repositorio local para cada una de sus ramas. REQ. 1.4: El adaptador debe permitir consultar la información de cualquier commit de un repositorio local. REQ. 1.5: El adaptador debe permitir consultar la información de cualquier árbol de cualquier commit de un repositorio local. REQ. 1.6: El adaptador debe permitir consultar la información de cualquier blob (fichero) de cualquier árbol de un repositorio local.
A partir del REQ. 2, consultas a GitHub:
REQ. 2.1: El adaptador debe permitir consultar las ramas (branches) de un repositorio en GitHub. REQ. 2.2: El adaptador debe permitir consultar la lista de commits de un repositorio en GitHub para cada una de sus ramas. REQ. 2.3: El adaptador debe permitir consultar la información de cualquier commit de un repositorio en GitHub. REQ. 2.4: El adaptador debe permitir consultar la información de cualquier árbol de cualquier commit de un repositorio en GitHub. REQ. 2.5: El adaptador debe permitir consultar la información de cualquier blob (fichero) de cualquier árbol de un repositorio local.
Sentadas estas bases, se expone el diseño obtenido para satisfacer los requisitos.
3.2.2. Diseño del adaptador La API (adaptador) recibe peticiones de la plataforma EzWeb y es a ella a quien contesta. Por motivos de clarificar la solución, al ser los gadgets los que inician la petición avisando a EzWeb para que este dialogue con la API y les devuelva la información, se considera más oportuno obviar la plataforma en los diagramas de contexto. Por ello, el diagrama de contexto del adaptador es el siguiente:
39
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Gadget I Adaptador (API) Gadget II Gadget III
Figura 3.8 Las entidades externas identificadas son (figura 3.8):
Git-commits: El usuario manipula este gadget para obtener información sobre los repositorios git locales y en github. Git-tree: Git-commits ordena a este gadget que solicite información asociada con árboles a la API. Git-file: Git-tree ordena a este gadget que solicite información asociada con ficheros a la API. GitHub: La API solicitará a este servicio Web la información de los repositorios hospedados en él.
A partir de las entidades externas y de los requisitos, se ha definido la siguiente lista de acontecimientos:
40
El usuario ha configurado git-commits y este se asegura de que la API funcione correctamente. El usuario ha configurado acceso local y se le tiene que mostrar la lista de repositorios disponible. El usuario ha configurado acceso local y seleccionado repositorio y se le tienen que mostrar las ramas, commits y datos de cada commit para dicho repositorio. El usuario ha configurado acceso a GitHub y seleccionado repositorio y se le tienen que mostrar las ramas, commits y datos de cada commit para dicho repositorio. Git-tree solicita la información de un árbol local. Git-tree solicita la información de un árbol de GitHub. Git-file solicita la información de un fichero local. Git-file solicita la información de un fichero de GitHub.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Se muestra en la siguiente tabla (tabla 3.1), la relación de métodos diseñados y los requisitos que cubren, para luego ser desarrollados en el apartado de implementación:
Método
Nombre
Requisitos Cubiertos
MET. 1
Api
REQ. 3
MET. 2
Get_directory
REQ. 1.1
MET. 3
Get_branches
REQ. 1.2
MET. 4
Get_commits
REQ. 1.3
MET. 5
Get_head
REQ. 1.4
MET. 6
Get_tree
REQ. 1.5
MET. 7
Get_blob
REQ. 1.6
MET. 8
Get_branches_github
REQ. 2.1
MET. 9
Get_commits_github
REQ. 2.2, REQ. 2.3
MET. 10
Get_tree_github
REQ. 2.4
MET. 11
Get_blob_github
REQ. 2.5
Tabla 3.1
3.2.3. Implementación del adaptador 3.2.3.1. MET. 1 – Api Este método es el encargado de comprobar que la URL que se ha configurado en los gadgets es correcta, es decir, que se corresponde con un servicio web que contiene la API programada. El usuario podría introducir una URL de un servicio web cualquiera, pero como ni entenderá los parámetros ni devolverá la misma respuesta, el gadget
41
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
git-commits lanzará un mensaje de error al usuario no dejándole proseguir hasta que configure una API adecuada.
MET. 1
Api
URI
/gitapi/api/
Método REST
GET
Descripción
Devuelve un “OK” para indicar que la petición ha llegado.
Tabla 3.2 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Tabla 3.3 Para que el método api devuelva lo que el gadget está esperando, los parámetros deben tener los siguientes valores:
Op: “-1” Github: “cualquiera”
op debe valer “-1”, al recibir este valor, la API contestará con el texto “Ok”. En cualquier otro caso dará error.
42
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
La petición ha llegado a la API
Bad Request
400
Los parámetros de la solicitud son incorrectos
Tabla 3.4 La respuesta a esta petición es la siguiente: Respuesta del servicio OK
Tabla 3.5 Este método es muy sencillo, al sólo servir para asegurarnos de que la URL es correcta y no hay problemas en la conexión de red.
3.2.3.2. MET. 2 – Get_directory La API, como se indica en el manual de usuario, tiene configurado un directorio a partir del cual los subdirectorios que descuelgan se corresponden cada uno con un repositorio git local. De esta forma, este método leerá el directorio configurado por el usuario y le devolverá el listado de subdirectorios que incluya. MET. 2
Get_directory
URI
/gitapi/api/
Método REST
GET
Descripción
Lee el directorio configurado en settings.py y devuelve la lista de subdirectorios que contiene en formato JSON.
Tabla 3.6 43
[PROYECTO FINAL DE CARRERA]
Mario Mira Boronat
Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Tabla 3.7 Para invocar a este método la configuración de los parámetros debe ser:
Op: 0 Github: 0
Con esta combinación se ejecuta el método get_directory. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Directorio bien configurado, devuelve el listado de subdirectorios
Bad Request
400
Los parámetros de la solicitud son incorrectos o el directorio está mal configurado.
Tabla 3.8 La respuesta a esta petición sigue el formato JSON y es: Respuesta del servicio [lista_repositorios]
Tabla 3.9
44
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Como se observa, si la petición está correctamente formulada, esta devolverá la lista de subdirectorios del directorio configurado, que se corresponderán con los repositorios git locales de la máquina.
3.2.3.3. MET. 3 – Get_branches Dado el nombre de un repositorio, la API devuelve la lista de ramas (branches) que tiene asociado.
MET. 3
Get_branches
URI
/gitapi/api/
Método REST
GET
Descripción
Abre el repositorio proporcionado como parámetro y obtiene el número de branches y sus nombres.
Tabla 3.10 Los parámetros requeridos para la correcta invocación de este método son los siguientes:
Parámetros del recurso Parámetro
Descripción
op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio local al que se desea acceder.
Tabla 3.11
45
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Para invocar a este método la configuración de los parámetros debe ser:
Op: 1 Github: 0 Repository: string
Con esta combinación se ejecuta el método get_branches.
Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve la lista de branches del repositorio. Como mínimo siempre será una.
Bad Request
400
Los parámetros de la solicitud son incorrectos o el nombre del repositorio es incorrecto.
Tabla 3.12 La respuesta a esta petición sigue el formato JSON y es:
Respuesta del servicio {branches: n_branhces, branchN: name}
active_branch:
name,
branch0:
name,
…,
Tabla 3.13 La respuesta del servicio indicda en la tabla 3.13 es:
46
Branches: Número de branches del repositorio. Active_branch: Rama activa en el reposiotrio. Branch0…branchN: Nombres de todas las ramas, desde la primera hasta el valor indicado por branches
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.2.3.4. MET. 4 – Get_ commits Este método recibe el nombre de un repositorio, una rama y el número de página solicitado. La API devuelve hasta 10 commits por página, indicando si hay o no más páginas disponibles. Para averiguar si hay o no páginas disponibles, la API comprobará que en esa página hay 10 commits y luego consultará si hay más commits, de haberlos, lo indicará. MET. 4
Get_commits
URI
/gitapi/api/
Método REST
GET
Descripción
Abre el repositorio proporcionado como parámetro, selecciona la rama proporcionada y obtiene hasta 10 commits según el número de página. Adicionalmente indica si hay más páginas disponibles para futuras consultas.
Tabla 3.14 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio local al que se desea acceder.
Branch
Indica la rama sobre la que se realiza la consulta.
Page
Número de página de la lista de commits.
Tabla 3.15
47
[PROYECTO FINAL DE CARRERA]
Mario Mira Boronat
Para invocar a este método la configuración de los parámetros debe ser:
Op: 2 Github: 0 Repository: string Branch: string. Page: integer
Con esta combinación se ejecuta el método get_commits. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve hasta 10 commits del repositorio según la página indicada. Indica si hay más páginas disponibles.
Bad Request
400
Los parámetros de la solicitud son incorrectos o el nombre del repositorio es incorrecto.
Tabla 3.16 La respuesta a esta petición sigue el formato JSON y es: Respuesta del servicio {“next_page”: boolean, “commits”: n_commits, “commit1”: [SHA1_commit, SHA1_tree, author, author_email, authored_date, committer, committer_email, committed_date, message]…,”commitN”: [parameter_list]}
Tabla 3.17 La respuesta del servicio indicada en la tabla 3.17 es:
48
Next_page: Flag que indica si hay más páginas disponibles o no. Commits: Número total de commits devueltos, 10 como máximo por página.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Commit1…CommitN: Lista de commits, seguidos de su lista de parámetros Parameter_list: Lísta de parámetros de cada commit, en este orden: o SHA1_commit: Hash del repositorio git que identifica de forma unívoca a este commit o SHA1_tree: Hash del repositorio git que identifica de forma unívoca al árbol asociado a este commit o Author: Nombre del autor del código o Author_email: Email del autor o Authored_date: Fecha de creación del código. o Committer: Nombre del usuario que ha realizado el commit o Committer_email: Email del committer o Committed_date: Fecha de realización del commit. o Message: Mensaje asociado al commit.
3.2.3.5. MET. 5 – Get_head Funciona de la misma forma que el método anterior, pero en este caso sólo devuelve un único commit. Para que lo haga, hay que proporcionarle el nombre del repositorio, el nombre de la rama y el hash SHA1 del commit. MET. 5
Get_head
URI
/gitapi/api/
Método REST
GET
Descripción
Abre el repositorio proporcionado como parámetro, selecciona la rama proporcionada y consulta los datos del commit pasado como parámetro.
Tabla 3.18
49
[PROYECTO FINAL DE CARRERA]
Mario Mira Boronat
Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio local al que se desea acceder.
Branch
Indica la rama sobre la que se realiza la consulta.
Commit
Hash del commit al que se desea acceder
Tabla 3.19 Para invocar a este método la configuración de los parámetros debe ser:
Op: 3 Github: 0 Repository: string Branch: string commit: sha1
Con esta combinación se ejecuta el método get_head. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve la solicitado.
Bad Request
400
Los parámetros de la solicitud son incorrectos o el nombre del repositorio es incorrecto.
Tabla 3.20
50
información
asociada
al
commit
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
La respuesta a esta petición sigue el formato JSON y es: Respuesta del servicio {“commit”: [parameter_list]}
Tabla 3.21 La respuesta del servicio indicada en la tabla 3.21 es:
Parameter_list: Lísta de parámetros de cada commit, en este orden: o SHA1_commit: Hash del repositorio git que identifica de forma unívoca a este commit o SHA1_tree: Hash del repositorio git que identifica de forma unívoca al árbol asociado a este commit o Author: Nombre del autor del código o Author_email: Email del autor o Authored_date: Fecha de creación del código. o Committer: Nombre del usuario que ha realizado el commit o Committer_email: Email del committer o Committed_date: Fecha de realización del commit. o Message: Mensaje asociado al commit.
51
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.2.3.6 MET. 6 – Get_tree En este caso el gadget git-tree solicita la información asociada a un árbol. La API contestará con el listado de ficheros y directorios de ese árbol. Se debe tener en cuenta que un directorio se corresponde con otro árbol y si se desea obtener la lista de dicho árbol/directorio, se deberá realizar otra petición a la API. MET. 6
Get_tree
URI
/gitapi/api/
Método REST
GET
Descripción
Abre el árbol asociado a la clave SHA1 solicitada. Requiere indicar el repositorio al que pertenece.
Tabla 3.22 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio local al que se desea acceder.
Tree
Hash del árbol al que se desea acceder
Tabla 3.23 Para invocar a este método la configuración de los parámetros debe ser:
52
Op: 4 Github: 0
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Repository: string tree: sha1
Con esta combinación se ejecuta el método get_tree. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve la solicitado.
Bad Request
400
Los parámetros de la solicitud son incorrectos o el nombre del repositorio es incorrecto.
información
asociada
al
árbol
Tabla 3.24 La respuesta a esta petición sigue el formato JSON y es: Respuesta del servicio {{“node0”: {“type”: {parameter_list}}
type,
“name”:
name,
“id”:
id},…,{“nodeN”:
Tabla 3.25 La respuesta del servicio indicada en la tabla 3.25 es:
node0…nodeN: Lista de nodos del árbol, a cada nodo le corresponde una lista de parámetros. Parameter_list: Lísta de parámetros de cada nodo del árbol, en este orden: o Type: Tipo del nodo, puede ser “tree” o “blob”. Tree: Se corresponde con un directorio, que contiene a su vez más nodos Blob: Fichero o Name: Nombre del nodo (fichero o directorio) o Id: Hash SHA1 del nodo (blob o tree)
53
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.2.3.7. MET. 7 – Get_blob Se encarga de devolver el contenido del fichero pedido. Se debe indicar el nombre del repositorio y el hash SHA1 del blob. MET. 7
Get_blob
URI
/gitapi/api/
Método REST
GET
Descripción
Devuelve el contenido del fichero correspondiente con el blob solicitado.
Tabla 3.26 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio local al que se desea acceder.
Blob
Hash del fichero al que se desea acceder
Tabla 3.27 Para invocar a este método la configuración de los parámetros debe ser:
Op: 5 Github: 0 Repository: string blob: sha1
Con esta combinación se ejecuta el método get_blob.
54
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve el contenido del fichero solicitado
Bad Request
400
Los parámetros de la solicitud son incorrectos o el nombre del repositorio es incorrecto.
Tabla 3.28 La respuesta a esta petición sigue el formato JSON y es: Respuesta del servicio {“data”: data, “mime”: mime-type, “size”: bytes}
Tabla 3.29 La respuesta del servicio indicada en la tabla 3.29 es:
data: Cadena de caracteres con el contenido del fichero (texto). Mime: Mime-type10 del fichero. Size: Tamaño del fichero en bytes.
10
Multipurpose Internet Mail Extensions (MIME) es un estándar de internet que extiende el format de los e-mails. En este contexto nos indica si el contenido es texto, imagen, o texto no ASCII.
55
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.2.3.8. MET. 8 – Get_branches_github Este método se utiliza para acceder a las ramas de un repositorio GitHub. Se necesita proporcionar el nombre de usuario y el nombre del repositorio de GitHub. MET. 8
Get_branches_github
URI
/gitapi/api/
Método REST
GET
Descripción
Devuelve las ramas de un repositorio de GitHub. Un repositorio de GitHub se define por un nombre de usuario y un nombre de repositorio.
Tabla 3.30 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio remoto al que se desea acceder.
User
Nombre del usuario que es propietario del repositorio en GitHub
Tabla 3.31 Para invocar a este método la configuración de los parámetros debe ser: 56
Op: 1 Github: 1 Repository: string
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
user: string
Con esta combinación se ejecuta el método get_branches_github. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve las ramas del repositorio
Bad Request
400
Los parámetros de la petición son incorrectos, es imposible acceder al servicio GitHub o no existe el par usuario/repositorio solicitado.
Tabla 3.32 En el caso de las peticiones a GitHub, se mostrará primero el formato de la respuesta que proporciona el servicio y posteriormente el que da la API a los gadgets. GitHub provee a la API con esta información: Petición a GitHub http://github.com/api/v2/json/repos/show/user/repsitory_name/branc hes Respuesta de GitHub {“branches”:{“branch_name1”:”id1”,…,”branch_nameN”:”idN”}}
Tabla 3.33 Una vez parseada la respuesta, la API devuelve la información al gadget que la solicita en formato JSON: Respuesta del servicio {branches: n_branhces, branchN: name}
active_branch:
name,
branch0:
name,
…,
Tabla 3.34 57
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
La respuesta del servicio indicda en la tabla 3.34 es:
Branches: Número de branches del repositorio. Active_branch: Rama activa en el reposiotrio. Branch0…branchN: Nombres de todas las ramas, desde la primera hasta el valor indicado por branches 3.2.3.9. MET. 9 – Get_commits_github
Este método se utiliza para acceder a los commits de un repositorio GitHub. Se necesita proporcionar el nombre de usuario, el nombre del repositorio y la rama. MET. 9
Get_commits_github
URI
/gitapi/api/
Método REST
GET
Descripción
Devuelve una lista con todos los commits que proporciona GitHub y sus datos correspondientes.
Tabla 3.35 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio remoto al que se desea acceder.
User
Nombre del usuario que es propietario del repositorio en GitHub
branch
Nombre de la rama del repositorio.
Tabla 3.36 58
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Para invocar a este método la configuración de los parámetros debe ser:
Op: 2 Github: 1 Repository: string user: string branch: string
Con esta combinación se ejecuta el método get_commits_github. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve los commits que proporciona GitHub y su información.
Bad Request
400
Los parámetros de la petición son incorrectos, es imposible acceder al servicio GitHub o no existe el par usuario/repositorio solicitado.
Tabla 3.37 GitHub sólo nos devuelve los 30 últimos commits del repositorio. Tal y como está diseñada la API no se le puede solicitar commits más antiguos. Es por ello que la funcionalidad de paginar no está implementada en los accesos remotos. En la misma solicitud, se devuelven todos los datos de cada commit. GitHub provee a la API con esta información: Petición a GitHub http://github.com/api/v2/json/commits/list/user/repository/branch Respuesta de GitHub {“commits”:[{“parents”:[{“id”:id}],”author”:{“name”:name,”login”:l ogin,”email”:email},”url”:url,”id”:id,”committed_date”:date,”autho red_date”:date,”message”:message, “tree”:id,”committer”:{“name”:name,”login”:login,”email”:email}},{ “parents”:[id],…,N]}
Tabla 3.38 59
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Una vez parseada la respuesta, la API devuelve la información al gadget que la solicita en formato JSON: Respuesta del servicio {“commits”: n_commits, “commit1”: [SHA1_commit, SHA1_tree, author, author_email, authored_date, committer, committer_email, committed_date, message]…,”commitN”: [parameter_list]}
Tabla 3.39 La respuesta del servicio indicada en la tabla 3.39 es:
60
Next_page: Flag que indica si hay más páginas disponibles o no. Commits: Número total de commits devueltos, 10 como máximo por página. Commit1…CommitN: Lista de commits, seguidos de su lista de parámetros Parameter_list: Lísta de parámetros de cada commit, en este orden: o SHA1_commit: Hash del repositorio git que identifica de forma unívoca a este commit o SHA1_tree: Hash del repositorio git que identifica de forma unívoca al árbol asociado a este commit o Author: Nombre del autor del código o Author_email: Email del autor o Authored_date: Fecha de creación del código. o Committer: Nombre del usuario que ha realizado el commit o Committer_email: Email del committer o Committed_date: Fecha de realización del commit. o Message: Mensaje asociado al commit.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.2.3.10.
MET. 10 – Get_tree_github
Con este método, al igual que su análogo en acceso local, se obtienen los nodos de un árbol de un repositorio. MET. 10
Get_tree_github
URI
/gitapi/api/
Método REST
GET
Descripción
Devuelve una lista con todos los nodos de un árbol de un repositorio de GitHub. Los nodos podrán ser directorios o ficheros.
Tabla 3.40 Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository
Indica el nombre del repositorio remoto al que se desea acceder.
User
Nombre del usuario que es propietario del repositorio en GitHub
Tree
Identificador del árbol que se solicita
Tabla 3.41 Para invocar a este método la configuración de los parámetros debe ser:
Op: 4 Github: 1
61
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Repository: string user: string tree: sha1
Con esta combinación se ejecuta el método get_tree_github. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve los nodos del árbol solicitado.
Bad Request
400
Los parámetros de la petición son incorrectos, es imposible acceder al servicio GitHub o no existe el par usuario/repositorio solicitado.
Tabla 3.42 GitHub provee a la API con esta información: Petición a GitHub http://github.com/api/v2/json/tree/show/user/repository/id Respuesta de GitHub {“tree”:[{“name”:filename,”sha”:id,”mode”:file_mode,”type”:type},… ,nodei]}
Tabla 3.43 Una vez parseada la respuesta, la API devuelve la información al gadget que la solicita en formato JSON: Respuesta del servicio {{“node0”: {“type”: {parameter_list}}
type,
“name”:
Tabla 3.44
62
name,
“id”:
id},…,{“nodeN”:
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
La respuesta del servicio indicada en la tabla 3.44 es:
Next_page: Flag que indica si hay más páginas disponibles o no. Commits: Número total de commits devueltos, 10 como máximo por página. Commit1…CommitN: Lista de commits, seguidos de su lista de parámetros Parameter_list: Lísta de parámetros de cada commit, en este orden: o SHA1_commit: Hash del repositorio git que identifica de forma unívoca a este commit o SHA1_tree: Hash del repositorio git que identifica de forma unívoca al árbol asociado a este commit o Author: Nombre del autor del código o Author_email: Email del autor o Authored_date: Fecha de creación del código. o Committer: Nombre del usuario que ha realizado el commit o Committer_email: Email del committer o Committed_date: Fecha de realización del commit. o Message: Mensaje asociado al commit.
3.2.3.11. MET. 11 – Get_blob_github Al igual que su análogo de acceso local, con este método se obtienen los datos de un fichero, en este caso almacenado en GitHub. MET. 11
Get_blob_github
URI
/gitapi/api/
Método REST
GET
Descripción
Devuelve el contenido del fichero especificado
Tabla 3.45
63
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Los parámetros requeridos para la correcta invocación de este método son los siguientes: Parámetros del recurso Parámetro
Descripción
Op
Indica la operación que se quiere realizar.
Github
Indica el tipo de acceso que se va a utilizar.
Repository Indica el nombre del repositorio remoto al que se desea acceder. User
Nombre del usuario que es propietario del repositorio en GitHub
Blob
Identificador del fichero que se solicita
Tabla 3.46 Para invocar a este método la configuración de los parámetros debe ser:
Op: 5 Github: 1 Repository: string user: string blob: sha1
Con esta combinación se ejecuta el método get_blob_github. Código de respuestas del recurso Respuesta
Código
Descripción
Ok
200
Devuelve los nodos del árbol solicitado.
Bad Request
400
Los parámetros de la petición son incorrectos, es imposible acceder al servicio GitHub o no existe el par usuario/repositorio solicitado.
Tabla 3.47
64
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Con esta petición GiHub devuelve el contenido del blob en formato RAW : 11
Petición a GitHub http://github.com/api/v2/json/blob/show/user/repository/id Respuesta de GitHub Raw_text
Tabla 3.48 Una vez parseada la respuesta, la API devuelve la información al gadget que la solicita en formato JSON: Respuesta del servicio {“data”: data}
Tabla 3.49 La respuesta del servicio indicada en la tabla 3.49 es:
11
data: Cadena de caracteres con el contenido del fichero (texto).
Contenido original del fichero, sin tratamiento de ningún tipo
65
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3. Gadgets Cada gadget está formado de tres partes: El template, la lógica y la apariencia. El template de cada gadget viene definido por su fichero XML, que interpreta la plataforma EzWeb. En él, se describen varios campos como nombre, autor, email del autor, etc… No obstante, cabe resaltar los siguientes campos:
Preferencias: Las preferencias de un gadget sirven para poner un menú adicional con parámetros de configuración. En nuestro caso, no utilizamos esta funcionalidad de EzWeb, ya que los menús de configuración se harán manualmente con HTML. Propiedades: Las propiedades de la plataforma EzWeb son variables que se guardan en el servidor de sesión en sesión. Sirven para que en sucesivas ejecuciones del gadget, se recuerden datos de las anteriores sesiones. Wiring: Las variables de Wiring son las que permiten la comunicación con otros gadgets. Hay de dos tipos: Slots y Events. Los slots son variables de recepción de datos, EzWeb es la encargada de lanzar el manejador asociado a cada slot, que se haya definido, cuando otro gadget le envíe información. Los events son, al contrario que los slots, variables de envío de datos. Al igual que los anteriores, EzWeb será la encargada de pasar el mensaje de un event a un slot cuando así se le indique. Contexto: Este tipo de variables sirven para que el gadget tenga conocimiento de su entorno. EzWeb se encargará de actualizarlas siempre que cambien. Un ejemplo típico de su uso, es captura la altura y la anchura del gadget a medida que le usuario le cambia el tamaño.
La lógica la forma el fichero JavaScript. Para exponer esta parte del diseño, utilizaremos una aproximación clásica de análisis y diseño orientado a objetos, siguiendo el esquema del libro [int05].
66
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Es decir, en pimera instancia se expondrá un breve resumen de los requisitos de cada gadget y de los actores que intervienen en él. Tras los actores, se describen los casos de uso y uníendolos con el punto anterior obtenemos el diagrama de casos de uso. Con esto descrito, se aborda cada caso de uso de forma independiente, mostrando en primer lugar sus diagramas de contexto para entender las distinas fases (estados) por los que pasa. A continuación se muestran sus diagramas de secuencia, que sirven para ver la interacción entre clases. En segunda instancia se expone la implementación, empezando por el diagrama de clases y continuando por exponer por cada caso de uso todos sus métodos junto con una descripción textual de cómo funciona cada uno. Por último abordamos las partes importantes del template y unas capturas y breve descripción del interfaz de usuario. Cabe destacar, que el cuarto gadget github-browser, al ser adicional al proyecto, no se plasmarán sus diseños técnicos, directamente su interfaz de usuario para ver su funcionamiento.
3.3.1. Git-file 3.3.1.1. Captura de Requisitos El objetivo de este gadget es mostrar los ficheros proporcionados por el gadget git-tree. Para ello accederá al adaptador (API REST) ubicado en la URL que también es proporcionada por dicho gadget. Deberá mostrar el fichero con la mejor apariencia posible y acordarse en futuros usos del último fichero al que accedió para mostrarlo.
67
Mario Mira Boronat
3.3.1.1.1.
[PROYECTO FINAL DE CARRERA]
Actores
Usuario Es la persona que utiliza el gadget. De por sí, su única tarea es visualizar la información proporcionada por el gadget. Adaptador Es la API REST que proporciona los datos que el gadget solicita, en este caso, contenido de blobs (ficheros). Git-tree Es otro gadget del sistema, que le envía a git-file los datos del fichero que debe visualizar, a través del wiring de EzWeb. EzWeb Cada vez que el usuario modifique el tamaño del gadget, EzWeb le indicará a través de las variables de contexto los nuevos valores.
3.3.1.1.2. Identificación y descripción de los casos de uso Iniciar el gadget: El usuario agregará a la plataforma EzWeb el gadget o iniciará la plataforma en su navegador con el gadget en su workspace. En este caso el gadget comprobará si está configurado. De estarlo, pasará a mostrar el fichero de su última ejecución. De no estarlo, mostrará una ventana a la espera de que le llegue la configuración a través de EzWeb. Mostrar el fichero: Git-tree le proporcionará al gadget la información del fichero al que debe acceder. El gadget guardará la configuración de esta información que acaba de recibir. Se bloqueará, enviará la señal de bloqueo a git-tree y le pedirá al adaptador que le obtenga los datos de dicho fichero. Una vez obtenidos los datos, los mostrará por pantalla, desbloqueándose y enviando la señal de desbloqueo a git-tree.
68
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Modificar el tamaño: El usuario modificará el tamaño del gadget en su navegador, por tanto, EzWeb le comunicará los nuevos valores al gadget. El gadget volverá a pintar el interfaz de usuario acomodándose a estos nuevos valores. Se observa la interacción entre los actores y los casos de uso en el siguiente diagrama de casos de uso. iniciador Iniciar_gadget Usuario iniciador iniciador
Adaptador Mostrar_fichero
Git-tree iniciador
EzWeb
Modificar_tamaño
Git-tree
Figura 3.3.1
El usuario es el encargado de iniciar todo el sistema. Iniciar_gadget llamará a Mostrar_fichero al empezar la ejecución para que muestre los datos. Si git-tree envía un fichero para ser visualizado, también iniciará este caso de uso. Durante su ejecución interactuará con el adaptador (para pedir los datos) y con git-tree (para realizar tareas de sincronismo). Por último, EzWeb mediante las variables de contexto del sistema, avisará de cambios en el tamaño de el interfaz de usuario al gadget, arrancando Modificar_tamaño.
3.3.1.1.3.
Diagramas de contexto
Para describir de forma más detallada el comportamiento de cada caso de uso, recurrimos a los diagramas de contexto.
69
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.1.1.3.1.
Iniciar_gadget
Inicio sistema configuración recibida
Comprobar configuración
error
Esperar configuración
Salir Figura 3.3.2 Iniciar_gadget lo primero que hace tras ser ejecutado es comprobar si está configurado correctamente. Si no lo está, pasa a mostrar una ventana de información en la que indica que está a la espera de recibirla. Una vez recibida, o en el caso de estar correctamente configurado, saldrá de este caso de uso para pasar al siguiente, mostrar_fichero.
70
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.1.3.2.
Mostrar_fichero
Inicio sistema
Guardar configuración
Ok
Enviar señal de bloqueo
Ok
Pedir datos
Ok
error
Bloquearse
Recepción de datos
Desbloquearse
Desbloquearse
Ok
Enviar desbloqueo
Ok
Enviar desbloqueo
Ok
Mostrar datos
Salir
Figura 3.3.3 Este escenario, como se vio en el diagrama de casos de uso, puede ser iniciado tanto por git-tree como por iniciar_gadget. Lo primero que hará será guardar la configuración recibida, ya que puede haber cambiado (git-tree siempre envía el fichero a acceder y la configuración necesaria para ello). Posteriormente enviará una señal de
71
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
bloqueo a git-tree (por wiring) para que muestre una ventana de “loading” (para que el usuario sepa que se está a la espera de los datos). Luego, hará la petición de los datos al adaptador y se bloqueará a sí mismo (mostrará la misma ventana de carga). Una vez lleguen los datos, estos pueden llegar correctamente o puede llegar un error. Si llega un error, el gadget se desbloquea y desbloquea a git-tree, mostrando una ventana de error y saliendo del caso de uso. Si los datos llegan correctamente, también se desbloqueará y desbloqueará a gittree, pero en este caso mostrara los datos obtenidos por pantalla.
3.3.1.1.3.3.
Modificar_tamaño
Inicio sistema
Modificar tamaño
Salir Figura 3.3.4
Este caso de uso es muy sencillo, pero es interesante reflejarlo en el diseño ya que posteriormente en la fase de desarrollo veremos como gracias a él, podemos explicar la comunicación entre EzWeb y los gadgets mediante las variables de contexto. En este caso, el usuario modificará el tamaño del gadget y será EzWeb el que notifique al gadget mediante las variables de contexto para que este reajuste el interfaz de usuario en consecuencia.
72
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.2.
Diseño
Con los requisitos mostrados anteriormente y teniendo en cuenta los actores del sistema, vamos a describir los diagramas de secuencia de cada caso de uso. En ellos, veremos la interactuación entre los componentes del diseño.
3.3.1.2.1.
Diagrama de secuencia para “Iniciar gadget”
:Git_file
Usuario iniciar()
mostrar_fichero()
Figura 3.3.5 El usuario interactúa con Git_file para iniciar el sistema, el cual pasa a la fase de mostrar_fichero.
73
Mario Mira Boronat
3.3.1.2.2.
[PROYECTO FINAL DE CARRERA]
Diagrama de secuencia para “Mostrar fichero”
:Git_file
Git_tree
:Adaptador
enviar_datos(fichero, config)
guardar_config()
bloquear()
Obtener_fichero(parámetros)
bloquear() fichero
desbloquear() desbloquear()
Figura 3.3.6 Git_tree o el método iniciar_gadget (no representado, al ser el mismo diagrama de secuencia) inician el proceso. Lo primero es guardar la configuración recibida, para futuras sesiones. A continuación, se envía un mensaje de bloqueo a Git_tree mientras se obtienen los datos del adaptador para el “fichero” solicitado. Git_file envía un mensaje asíncrono al adaptador para que le envíe los datos. Mientras la petición se procesa, se bloquea, mostrando la ventana al usuario de “esperando datos”. Cuando llegan los datos (fichero), Git_file se desbloquea, muestra los datos al usuario y envía la señal de desbloqueo a Git_tree para finalizar la tarea.
74
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.2.3.
Diagrama de secuencia para “Modificar tamaño”
:Git_file
EzWeb
cambio_tamaño(altura, anchura)
modificar_interfaz()
Figura 3.3.7 El usuario modifica el tamaño del gadget, señal que intercepta EzWeb y envía mediante las variables de contexto (altura, anchura) a git_file. Éste los recibe y cambia el interfaz de usuario acorde a lo recibido.
75
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.1.3. Implementación
3.3.1.3.1. Clases Dado que git-file es un gadget sencillo, toda su programación consta de una única clase, la clase file. Esta clase esta compuesta de varios métodos y atributos, que describimos en el diagrama de clases. Con este diagrama, se explicarán por cada caso de uso, qué métodos y atributos participan y cual es su funcionalidad.
File +wrapper_height_offset +wrapper_width_offset +file_height_offset +file_width_offset +header_width_offset +repository +url +file +filename +is_configured +github
+first_load +eventSync +slotFile +slotRepository +slotURL +saved_repository +saved_url +saved_file +alternatives +mainAlternative
+init() +createUserInterface() +repaint() +loading(enable) +ConfigWait(enable) +save() +restore() +getFile() +validFile() +errorFile() +displayFile(resp) +displayError() +displayException() +setURL(msg) +setRepository(msg) +setFile(msg) +Send_Syn() +Send_Fin()
Figura 3.3.8
76
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.3.2.
Métodos por caso de uso
3.3.1.3.2.1.
Iniciar_gadget
Método
Nombre
Atributos
MET. 1
Init
Alternatives, mainAlternative, eventSync, slotFile, slotRepository, slotURL, saved_repository, saved_url, saved_file
MET. 2
MET. 3
MET. 4
Restore
createUserInterface
Parámetros
saved_repository, saved_file, saved_url, repository, github, url, file, filename, is_configured Wrapper_height_offset, Wrapper_width_offset, File_height_offset, File_width_offset, Header_width_offset, is_configured, mainAlternative
ConfigWait
-
-
-
-
enable
Tabla 3.3.1 MET. 1 – Init Es el primero que se ejecuta cuando se inicia el gadget. Por ello, su labor es inicializar variables que hagan falta a lo largo de la ejecución. Las variables más importantes que inicializa son las que utiliza la plataforma EzWeb, estas son:
eventSync: La variable de sincronización con git-tree, hay que indicarle a EzWeb que la asocie con la descrita en el template (XML) slotFile: Variable para recibir datos de git-tree, se ha de ligar con un manejador, en este caso setfile(). Cada vez que su valor sea modificado, EzWeb lanzará el manejador. slotRepository: Variable para recibir datos de git-tree, se liga con setRepository(), de la misma forma que la anterior.
77
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
slotURL: Variable para recibir datos de git-tree, al igual que las dos anteriores, se liga con su manejador setURL(). saved_repository: Variable para almacenar datos entre sesiones. Hay que asociarla a la variable creada en el template (XML) con este propósito para que EzWeb la reconozca. Almacena el nombre del repositorio a acceder. saved_url: Al igual que la anterior, se declara para que EzWeb la reconozca, alberga la URL del adaptador (API). saved_file: Como sus dos antecesoras, se asocia a su declaración en el template. En este caso guarda el hash SHA1 del blob (fichero) accedido.
Posteriormente crea el contenedor para el interfaz de usuario utilizando los atributos alternatives y mainAlternative. A continuación llama al método restore() que cargará los datos almacenados de sesiones anteriores, lanza createUserInterface() para crear el interfaz en sí y por último ejecuta repaint() para redimensionar el interfaz de usuario al tamaño actual del gadget. MET. 2 – Restore Es el encargado de cargar los datos de la sesión anterior. Gracias a que init ha inicializado las variables saved_repository, saved_file y saved_url, el método puede utilizarlas para su propósito. Primero comprueba que estas variables contentan información, si no la contienen, finaliza su ejecución (lo que significará que el gadget no está configurado). Si contienen información, carga todos los datos y rellena los siguientes atributos:
78
repository: Le asignará el valor de saved_repository. En el caso de acceso a github almacenará el usuario del repositorio y su nombre, con el formato user;repository. Si por el contrario el acceso es local, sencillamente almacenará el nombre del repositorio. Para discernir entre ambos, basta con que compruebe que en la información almacenada está el carácter “;”. url: Le asignará el valor prorpocionado por saved_url. Esta variable almacena la dirección URL del adaptador (API).
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
file: Le asignará parte del valor de saved_file. Esta última almacena el hash SHA1 del blob (fichero) a acceder y su nombre separados por un “;”. En este caso, la variable file se queda con el hash. filename: Le asignará parte del valor de saved_file. Esta variable se queda con la otra parte, el nombre del fichero a acceder. Una vez cargadas las variables finaliza su ejecución.
MET. 3 – createUserInterface Los detalles de la implementación del interfaz gráfico quedan para una sección posterior. A grandes rasgos, se crea el interfaz de usuario y se almacena en el atributo mainAlternative. Lo importante en este apartado es describir la parte lógica de la solución. En este caso, tras crear el interfaz gráfico, createUserInterface comprueba si el gadget está configurado mediante el atributo is_configured. De estar configurado, restore() le habría asignado el valor true. Si está configurado, se llama a get_file(), para que procese la petición al adaptador. Si no está configurado, se ejecuta ConfigWait() que deja el gadget bloqueado a la espera de la recepción de un mensaje por parte de git-tree. MET. 4 – ConfigWait Tiene un parámetro de entrada enable. Es una variable booleana, con lo que puede tomar los valores:
true: Desactiva el interfaz de usuario, dejando al gadget bloqueado a la espera de la llegada de la configuración del sistema mostrando un mensaje a pantalla completa. false: Activa el interfaz de usuario, quitando el mensaje.
79
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.1.3.2.2.
Mostrar_fichero
Método
Nombre
Atributos
Parámetros
MET. 5
getFile
github, repository, url, file
-
MET. 6
validFile
Filename
-
MET. 7
errorFile
MET. 8
displayFile
MET. 9
displayError
-
-
MET. 10
displayException
-
-
MET. 11
setURL
url
msg
MET. 12
setRepository
Repository, github
msg
MET. 13
setFile
file, filename, is_configured
msg
MET. 14
Send_Syn
eventSync
-
MET. 15
Send_Fin
eventSync
-
MET. 16
Loading
MET. 17
Save
filename, first_load
-
resp
Enable
saved_repository, saved_url, saved_file
Tabla 3.3.2 MET. 5 – getFile Se encarga de preparar la llamada al adaptador. Primero envía la señal de sincronización a git-tree para que se bloquee mediante Send_Syn(). A continuación muestra la ventana de “cargando” para bloquear la interacción del usuario mediante loading(true). Si el nombre del fichero es válido (comprobación llamando a validFile()), entonces realiza la llamada según sea local o a github. Si el no era válido, llamará a errorFile().
80
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Para saberlo, comprueba el estado del atributo github, si es true, la petición al adaptador será para un repositorio de github, con lo que a través del atributo repository obtendrá el nombre de usuario y el nombre del repositorio a pedir. Si es false, la petición es de un repositorio local. En cualquiera de los dos casos, se realiza la petición al adaptador utilizando los atributos repository, url y file. Para realizar la petición, invoca el método de EzWeb sendGet(url, successHandler, errorHandler, exceptionHandler), al que hay que pasarle como argumento la URL a la que va dirigida la petición, el manejador si la petición va correctamente (successHandler) y los de error y excepción (errorHandler y exceptionHandler respectivamente). En el caso de getFile, los manejadores son:
SuccessHandler: displayFile(resp) ErrorHandler: displayError() ExceptionHandler: displayException()
El método finaliza su ejecución al hacer la petición. Cuando EzWeb reciba respuesta, reanudará la ejecución del gadget según si ha sido procesada correctamente o no. MET. 6 – validFile Su tarea es comprobar si la extensión del fichero se corresponde con alguna de las que el gadget es capaz de mostrar. Básicamente el gadget puede mostrar cualquier extensión que se corresponda con un fichero de texto. Si la extensión es una imagen o un fichero binario, la función devolverá false. MET. 7 – errorFile Desbloquea el gadget mediante loading(false), desbloquea al gadget git-tree con la llamada Send_Fin() y muestra un mensaje por pantalla indicando que la extensión del fichero seleccionado no es soportada por el sistema.
81
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET. 8 – displayFile Recibe como argumento resp. En éste, EzWeb almacena la respuesta del adaptador a la petición asíncrona. Como se ha indicado anteriormente, esta respuesta viene codificada en formato JSON, con lo que lo primero será evaluarla para ver su contenido. Una vez evaluada, extraemos el nombre del fichero y lo almacenamos en el atributo filename para futuras referencias. Preparamos el interfaz de usuario y extraemos el contenido del fichero de la respuesta. Si es la primera vez que se ejecuta el gadget, el atributo first_load estará a true, con lo que el gadget directamente mostrará la información por pantalla invocando a la librería “EditArea”, para que le dé formato, y pondrá first_load a false. Si por el contrario, no es la primera llamada a este método, primero eliminará la información de la anterior llamada del interfaz de usuario y luego mostrará la nueva. MET. 9 – displayError Desbloquea el gadget mediante loading(false), desbloquea al gadget git-tree con la llamada Send_Fin() y muestra un mensaje por pantalla indicando que ha habido un error durante la petición al adaptador. MET. 10 – displayException Igual que el método anterior, solo que se ejecuta en el caso de haber alguna excepción en el código (por ejemplo, al evaluar la respuesta del adaptador). MET. 11 – setURL Gracias a que el método 1, init, ha configurado las variables “slot”, cuando EzWeb recibe medinate wiring, que otro gadget le ha enviado información a git-file, ejecuta esta función. En este caso cuando se envía información a la variable slotURL. Recibe como parámetro msg, que contiene la información enviada al slotURL. La almacena en el atributo url.
82
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 12 – setRepository Al igual que la anterior, EzWeb lanza el método cuando se modifica la variable slotRepository, indicando el valor en el parámetro msg. Según la información recibida, almacena las variables github y repository. Puede recibir 2 tipos de mensajes:
User;repository: Este tipo de mensaje hace referencia al acceso a github, porque se necesitan los dos datos para acceder a los repositorios (usuario y nombre del repositorio). Por tanto, asigna true al atributo github y almacena esta cadena en repository. Repository: Si sólo recibe el nombre del repositorio, se trata de acceso local, con lo que asigna false a github y rellena repository con esta cadena.
MET. 13 – setFile De nuevo, este método es invocado por EzWeb cuando se modifica la variable slotFile, indicando su valor en el parámetro msg. En ella se recibe el hash SHA1 del blob (fichero) al que se desea acceder y el nombre del fichero, separados por “;”. Por tanto, el formato recibido es sha1;filename.
Sha1: Se almacena en el atributo file Filename: Se almacena en el atributo filename
Una vez guardados estos datos, este método es el encargado de iniciar la llamada al adaptador y de guardar los datos. Para ello, primero realiza una llamada al método save() y posteriormente a getFile(). MET. 14 – Send_Syn Asigna el valor “syn” al atributo eventSync. Al haber sido inicializada por init, EzWeb detecta la modificación y envía su valor al gadget conectado al evento. En el sistema planteado, el gadget receptor será git-tree, que se bloqueará al recibirlo.
83
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET. 15 – Send_Fin Asigna el valor “fin” al atributo eventSync. Funciona igual que el método anterior, solo que el resultado en este caso será que git-tree se desbloqueará. MET. 16 – Loading Recibe el parámetro enable. Es un parámetro de tipo boolean, si está a true, bloquea el interfaz de usuario mostrando un mensaje a pantalla completa indicando que le gadget está a la espera de recibir una petición del adaptador. Si por el contraro está a false, desbloquea el interfaz eliminando dicho mensaje. MET. 17 – save Cuando setFile() recibe un fichero que se desea visualizar, se llama a save() para que guarde los parámetros de la petición para futuras sesiones. De esta forma, utilizando las variables de preferencia de EzWeb, el gadget git-file almacena la URL del adaptador, el nombre del repositorio y el hash SHA1 del fichero al que se accede en los atributos saved_url, saved_repository y saved_file respectivamente.
3.3.1.3.2.3.
Modificar_tamaño
Método
Nombre
Atributos
MET. 18
repaint
Wrapper_height_offset, Wrapper_width_offset, File_height_offset, File_width_offset, Header_width_offset
Parámetros -
Tabla 3.3.3 MET. 18 – Repaint Se ejecuta cada vez que se modifican las variables de contexto del gadget. En este caso height y width. Es decir, cuando el usuario cambia
84
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
el tamaño del gadget, repaint se encarga de redimensionar utilizando width y height el interfaz de usuario. Los atributos: wrapper_height_offset, wrapper_width_offset, file_height_offset, file_width_offset y header_width_offset, son constantes para controlar el aspecto resultante de la redimensión.
3.3.1.3.3.
Template
Se describe en este apartado, las partes importantes del fichero XML (template) del gadget. Ellas son, las que configuran variables con EzWeb para luego poder utilizarlas en su implementación. De todo el template lo más importante son las variables de Wiring, que nos permiten comunicarnos con otros gadgets. En este caso, se necesita comunicar con el gadget git-tree, ya que cuando el usario hace click en cualquier fichero de este gadget, se le envia a través de sus eventos la información correspondiente para que git-file haga la petición a la API y muestre el fichero. slotFile
eventFile
slotRepository
eventRepository
slotURL
eventURL
eventSync
slotSync
Git-tree
Git-file
Figura 3.3.9 Como vemos en la figura 3.3.9, hay dos sentidos de la comunicación. Uno que va desde git-tree hasta git-file y otro en el sentido inverso. En el primer caso, git-tree le envía a git-file las variables eventFile, eventRepo y eventURL, que se corresponden con las ranuras slotFile, slotRepository y slotURL.
85
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
eventFile/slotFile: se encarga de transportar el hash SHA1 del fichero al que se debe acceder. Un hash SHA1 es una cadena alfanumérica de X caracteres. eventRepo/slotRepo: transporta el nombre del repositorio a acceder. Si el acceso es local el dato es un string con el nombre. Si el acceso es a GitHub, se envía el nombre del repositorio y el nombre del usuario asociado, con el formato “usuario;nombre”. El carácter “;” que no se va a encontrar en el nombre de un repositorio, es el que ocasionará que git-file sepa que debe hacer el acceso a GitHub. eventURL/slotURL: envía la dirección URL de la localización de la API REST que escuchará las peticiones del gadget. En segundo caso, el sentido de git-file a git-tree, encontramos una única variable, la variable de sincronización. eventSync/slotSync: Cada vez que git-file hace una petición asíncrona a la API (todas las peticiones son asíncronas, al utilizar la tecnología AJAX), envía una señal (un carácter) por este canal para bloquar a gittree y se bloquea a sí mismo. Cuando la API ofrece respuesta, el gadget se desbloquea y envía la señal de desbloqueo a git-tree.
86
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.3.3.1.
Propiedades Propiedades
<Platform.StateProperties> <Property name=”saved_file” type=”text” label=”saved_file” description=”File saved for the next sesion” /> <Property name=”saved_repository” type=”text” label=”saved_repository” description=”Repository saved for next sesion”/> <Property name=”saved_url” type=”text” label=”saved_url” description=”Django API’s URL for next sesion”/> </Platform.StateProperties>
Git-file.xml
Se han resaltado en negrita los tags que del fichero. Se procede ahora describir los campos:
Platform.StateProperties: Se pueden instanciar tantas como se quiera, en este caso se usan tres: o Saved_file: Almacenará el hash SHA1 del fichero que se está visualizando para futuras sesiones de uso. o Saved_repository: Según si estamos visualizando repositorios en local o en GitHub se almacenará una información u otra. En el caso local, se guarda el nombre del repositorio visualizado para futuras sesiones. En el caso del acceso a GitHub, se guarda tanto el nombre del repositorio como el nombre de usuario de github asociado al mismo. o Saved_url: Se guarda en este campo la URL de la API a la que se tienen que lanzar las peticiones para obtener los datos de los ficheros a visualizar.
87
Mario Mira Boronat
3.3.1.3.3.2.
[PROYECTO FINAL DE CARRERA]
Wiring Wiring
<Platform.Wiring> <Slot name=”slotFile” type=”text” label=”file” friendcode=”sha1file”/> <Slot name=”slotRepository” type=”text” label=”repository” friendcode=”repository”/> <Slot name=”slotURL” type=”text” label=”url” friendcode=”url”/> <Event name=”eventSync” type=”text” label=”sync” friendcode=”sync”/> </Platform.Wiring>
Git-file.xml
88
Platform.Wiring: Para comunicarse con otros gadgets, se utilizan las siguientes variables, que dividimos en slots y events. o Slots: slotFile: En esta ranura se recibirá el hash SHA1 referente al fichero que se desea visualizar en git-file. slotRepository: Se recibirá el nombre del repositorio en el caso de acceso local y el nombre del repositorio más el nombre de usuario de GitHub, en el caso de accesos remotos. slotURL: Aquí se recibe la URL de la API a la que hacer las peticiones de información. o Events: eventSync: Este evento se utiliza para avisar a otros gadgets que las peticiones a la API han finalizado (para sincronizarse).
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.1.3.3.3.
Contexto Contexto
<Platform.Context> <Context name=”user” type=”text” concept=”user_name”/> <GadgetContext name=”height” type=”text” concept=”heightInPixels”/> <GadgetContext name=”width” type=”text” concept=”widthInPixels”/> <GadgetContext name=”lockStatus” type=”text” concept=”lockStatus”/> </Platform.Context>
Git-file.xml
Platform.Context: o User: Nombre de usuario que esta utilizando la plataforma EzWeb. o Height: Altura del gadget. Para redimensionar el interfaz gráfico. o Width: Anchura del gadget. Para redimensionar el interfaz gráfico. o LockStatus: Indica el estado de bloqueo del gadget. Lo utiliza la librería extendida de EzWeb.
3.3.1.3.4.
Interfaz de usuario
Por último, se describe en este apartado el aspecto resultante del gadget, así como los métodos involucrados en la modificación del mismo.
89
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Git-file consta de cuatro estados del interfaz de usuario. El interfaz principal, dos mensajes de bloqueo (esperar configuración y esperar petición de la API) y los mensajes de error. Se presentan a continuación capturas de pantalla de cada uno de ellos.
Figura 3.3.10 La figura 3.3.10 muestra el interfaz principal del gadget.
90
En 1 podemos observar el nombre del fichero que se está mostrando. En 2 se muestra el contenido del fichero
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Figura 3.3.11
Este caso se corresponde a la invocaci贸n del m茅todo loading, que bloquea el gadget hasta que se reciba respuesta del adaptador.
Figura 3.3.12
91
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Este mensaje nos aparece cuando se instancia el gadget por primera vez y no está configurado. Desaparece en cuanto git-tree le envía la configuración mediante wiring.
Figura 3.3.13 Por último, la venta de los mensajes de error. El diseño que muestra es el que nos proporciona la librería extendida de EzWeb.
92
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Los métodos que afectan al interfaz de usuario son: Método Nombre
Descripción
MET. 3
createUserInterface Crea todas las capas y elementos del interfaz principal (fig X)
MET. 4
ConfigWait
Muestra el mensaje de la figura X
MET. 8
displayFile
Rellena el contenido del fichero en el interfaz principal (Número 2 en figura X). Para ello utiliza la librería EditArea.
MET. 9
displayError
Muestra un mensaje como el de la figura X pero con el texto asociado al error ocurrido.
MET. 10
displayException
Muestra un mensaje como el de la figura X pero con el texto asociado a la excepción generada.
MET. 16
Loading
Muestra el mensaje de la figura X
MET. 17
Repaint
Redimensiona 1 y 2 en la figura X según los nuevos valores
Tabla 3.3.4
3.3.2. Git-tree 3.3.2.1.
Captura de Requisitos
El objetivo de este gadget es mostrar los árboles asociados a los commits seleccionados por el gadget git-commits, así como enviar el fichero que se desea visualizar al gadget git-file. Para ello accederá al adaptador (API REST) ubicado en la URL que también proporciona gitcommits. Deberá mostrar el árbol con la mejor apariencia posible y acordarse en futuros usos del último árbol al que accedió para mostrarlo.
93
Mario Mira Boronat
3.3.2.1.1.
[PROYECTO FINAL DE CARRERA]
Actores
Usuario Es la persona que utiliza el gadget. Sus tareas serán visualizar el árbol del repositorio, seleccionar qué fichero desea visualizar y abrir carpetas del árbol. Adaptador Es la API REST que proporciona los datos que el gadget solicita, en este caso, el contenido de los árboles. Git-commits Es otro gadget del sistema, que le envía a git-tree los datos del árbol que debe visualizar, a través del wiring de EzWeb. A su vez, se realizarán tareas de sincronismo con él. Git-file Gadget del sistema que recibe los datos para mostrar un fichero. Gittree le enviará a petición del usuario de qué fichero quiere visualizar. A su vez, se realizan tareas de sincronismo con él. EzWeb Cada vez que el usuario modifique el tamaño del gadget, EzWeb le indicará a través de las variables de contexto los nuevos valores.
3.3.2.1.2.
Identificación y descripción de los casos de uso
Iniciar el gadget: El usuario agregará a la plataforma EzWeb el gadget o iniciará la plataforma en su navegador con el gadget en su workspace. En este caso el gadget comprobará si está configurado. De estarlo, pasará a mostrar árbol de su última ejecución. De no estarlo, mostrará una ventana a la espera de que le llegue la configuración a través de EzWeb.
94
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Mostrar árbol: Git-commits le proporcionará al gadget la información del árbol al que debe acceder. El gadget guardará la configuración de esta información que acaba de recibir. Se bloqueará, enviará la señal de boqueo a git-commits y le pedirá al adaptador que le obtenga los datos de dicho árbol. Una vez obtenidos, construirá el árbol para que se vea correctamente por pantalla, desbloqueándose y enviando la señal de desbloqueo a git-commits. Expandir árbol: Una vez un árbol está construido, puede contener directorios. Cuando el usuario desea abrir uno de estos directorios, el gadget git-tree pedirá al adaptador que obtenga los datos de su árbol asociado. Al obtenerlos, expandir árbol añadirá los nuevos datos al árbol ya mostrado por pantalla, ampliándolo. Esta nueva ampliación, a su vez, podrá contener más directorios. Sincronizar: Tanto git-commits como git-file, pueden enviar una señal de bloqueo a git-tree. Cuando esta señal llega, el gadget debe bloquarse hasta recibir la señal de desbloqueo. Enviar fichero: Con el árbol ya construido, si el usuario hace click en cualquier fichero, se envían los datos del mismo a git-file para que lo muestre en su interfaz. Para ello, se utilizan las variables wiring de EzWeb. Modificar tamaño: El usuario modificará el tamaño del gadget en su navegador, por tanto, EzWeb le comunicará los nuevos valores al gadget. El gadget volverá a pintar el interfaz de usuario acomodándose a estos nuevos valores. Se observa la interacción entre los actores y los casos de uso en el siguiente diagrama de casos de uso.
95
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
iniciador
Enviar_fichero iniciador Expandir_arbol
Usuario
Git-file
iniciador Iniciar_gadget iniciador
iniciador
Adaptador
Mostrar_arbol
Git-Commits iniciador iniciador
Sincronizar
Git-commits
Git-File iniciador
EzWeb
Modificar_tamaño
Figura 3.3.14
El usuario es el encargado de iniciar todo el sistema. Iniciar_gadget comprobará la configuración del sistema y según ésta, llamará o no a Mostrar_arbol para que muestre el árbol. Mostrar_arbol también puede ser iniciado por Git-commits debido a que este solicite que se muestre un árbol. Durante su ejecución interactuará con el adaptador (para pedir los datos) y con git-commits (para enviarle señales de sincronismo). En el caso en el cual el árbol contenga subdirectorios, el usuario podrá abrirlos. De hacerlo, se realizarán las mismas operaciones que con Mostrar_árbol, con la diferencia que el resultado deberá ser añadido en su correspondiente posición en el árbol. Es decir, expandir_arbol enviará señales de sincronización a git-commits, obtendrá los datos del adaptador y los incrustará al árbol anterior.
96
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Con el árbol pintado, independientemente del número de subdirectorios cargados, el usuario puede hacer click en cualquier fichero, lo cual pondrá en marcha el caso enviar_fichero, que mediante las variables de EzWeb mandará los datos del fichero al que se desea acceder a git-file para que lo muestre por pantalla. Git-tree se bloqueará siempre que reciba una señal de bloqueo por parte de git-commits o por parte de git-file. Se desbloqueará cuando reciba la señal de desbloqueo de los mismos. Esto es lo que refleja el caso de uso “sincronizar”. Por último, EzWeb mediante las variables de contexto del sistema, avisará de cambios en el tamaño del interfaz de usuario, lo que conllevará la ejecución de modificar_tamaño.
3.3.2.1.3.
Diagramas de contexto
Para describir de forma más detallada el comportamiento de cada caso de uso, recurrimos a los diagramas de contexto. 3.3.2.1.3.1. Iniciar_gadget
Inicio sistema configuración recibida
Comprobar configuración
error
Esperar configuración
Salir Figura 3.3.15 Iniciar_gadget tiene el mismo comportamiento que en el gadget gitfile. Lo pimero que hace tras ser ejecutado es comprobar si está configurado correctamente. Si no lo está, pasa a mostrar una ventana de información en la que indica que está a la espera de recibirla. Una vez recibida, o en el caso de estar correctamente configurado, saldrá de este caso de uso para pasar al siguiente, mostrar_arbol. 97
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.2.1.3.2. Mostrar_arbol Inicio sistema
Guardar configuración
Ok
Enviar señal de bloqueo
Ok
Pedir datos
Ok
Bloquearse
error
Recepción de datos
Desbloquearse
Desbloquearse
Ok
Enviar desbloqueo
Ok
Enviar desbloqueo
Ok
Mostrar datos
Figura 3.3.16 Salir
Nuevamente, su comportamiento es muy similar al caso de uso mostrar_fichero de git-file. Este escenario puede ser iniciado tanto por git-commits como por iniciar_gadget. Lo primero que hará será guardar la configuración recibida, para futuros accesos. Posteriormente enviará una señal de bloqueo a git-commits (por wiring) para que muestre una ventana de “loading”. Luego, hará la petición de los datos al adaptador y se bloqueará a sí mismo hasta que reciba la respuesta. Si la respuesta 98
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
es favorable, se desbloqueará, enviará la señal de desbloqueo y mostrará los datos obtenidos por pantalla. Si por el contrario, no lo es, realizará las mismas tareas de sincronismo pero en vez de los datos mostrará una pantalla de error al usuario.
3.3.2.1.3.3. Expandir_arbol Inicio sistema
Enviar señal de bloqueo
Ok
Pedir datos
Ok
Bloquearse
error
Recepción de datos
Desbloquearse
Desbloquearse
Ok
Enviar desbloqueo
Ok
Enviar desbloqueo
Ok
Mostrar datos
Figura 3.3.17 Salir
Expandir_arbol funciona exactamente igual que mostrar_arbol. Excepto en su inicio y su fin.
99
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
El iniciador de este caso de uso siempre será el usuario, se da cuando se desea acceder a algún subdirectorio del árbol. A diferencia de mostrar_arbol, no se guardará ninguna configuración, ya que esta no ha cambiado. Directamente se pedirán los datos al adaptador y se realizarán las tareas de sincronismo. Cuando se reciban los datos, si son erróneos, se mostrará error, si no lo son, se mostrarán por pantalla. Este es el otro punto de diferenciación respecto a mostrar_arbol, al mostrar los datos por pantalla, hay que respetar el anterior árbol, expandiendo los nuevos datos a partir del subdirectorio escogido.
3.3.2.1.3.4. Enviar_fichero
Inicio sistema
Enviar Fichero
Salir Figura 3.3.18 El usuario hará click en un fichero de los mostrados en el árbol. Por tanto, el gadget enviará los datos necesarios para realizar el acceso al mismo a git-file.
100
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.2.1.3.5. Sincronizar
Petición bloqueo
Bloquear
Desbloqueo
Desbloquear
Salir
Figura 3.3.19
Cuando el gadget recibe la petición de bloqueo de git-commits o de git-file se bloquea a la espera de recibir la señal de desbloqueo. Cuando la recibe, se desbloquea. Toda esta comunicación se realiza mendiante wiring. 3.3.2.1.3.6.
Modificar_tamaño
Inicio sistema
Modificar tamaño
Salir Figura 3.3.20 El usuario modificará el tamaño del gadget y será EzWeb el que notifique al gadget mediante las variables de contexto de este suceso, para que reajuste el interfaz de usuario.
101
Mario Mira Boronat
3.3.2.2.
[PROYECTO FINAL DE CARRERA]
Diseño
Con los requisitos mostrados anteriormente y teniendo en cuenta los actores del sistema, vamos a describir los diagramas de secuencia de cada caso de uso. En ellos, veremos la interactuación entre los componentes del diseño.
3.3.2.2.1. Diagrama de secuencia para “Iniciar_gadget”
:Git_tree
Usuario iniciar()
mostrar_arbol()
Figura 3.3.21 El usuario interactúa con Git_tree para iniciar el sistema, el cual pasa a la fase de mostrar_arbol.
102
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.2.2.2.
Diagrama de secuencia para “Mostrar árbol”
:Git_tree
Git_commits
:Adaptador
enviar_datos(arbol, config)
bloquear()
guardar_config() Obtener_arbol(parámetros)
bloquear() arbol
desbloquear() desbloquear()
Figura 3.3.22 Git_commits o el método iniciar_gadget inician el proceso. Lo primero es guardar la configuración recibida, para futuras sesiones. A continuación, se envía un mensaje de bloqueo a Git_commits mientras se obtienen los datos del adaptador para el “árbol” solicitado. Git_tree envía un mensaje asíncrono al adaptador para que le envíe los datos. Mientras la petición se procesa, se bloquea, mostrando la ventana al usuario de “esperando datos”. Cuando llegan los datos (el árbol), git_tree se desbloquea, muestra los datos al usuario y envía la señal de desbloqueo a git_commits para finalizar la tarea.
103
Mario Mira Boronat
3.3.2.2.3.
[PROYECTO FINAL DE CARRERA]
Diagrama de secuencia para “Expandir árbol”
:Git_tree
Usuario
:Adaptador
:Git_commits
expandir_arbol(nodo) bloquear()
Obtener_arbol(nodo)
bloquear() arbol
desbloquear() desbloquear()
Figura 3.3.23
El usuario desea expandir un nodo del árbol, con lo que hace click en él. Git_tree recibe la petición e inmediatamente bloque a git_commits para que el usuario no pueda realizar futuras peticiones hasta que no se complete la operación. A continuación, pide dicho nodo al adaptador, bloqueándose hasta recibir la respuesta. Cuando la recibe, se desbloquea y envía la señal de desbloqueo a git_commits. Por último, añade la nueva información recibida al árbol ya mostrado, descolgándola del nodo seleccionado.
104
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.2.2.4.
Diagrama de secuencia para “Enviar Fichero”
:Git_tree
Usuario
:Git_file
ver_fichero(nodo) visualizar_fichero(datos)
Figura 3.3.24 El usuario seleccionará un fichero de entre todos los del árbol para ser visualizado. Esto queda representado como un “nodo” del árbol. Cuando git_tree reciba la petición, enviará a git_file los datos para obtener su información. Estos datos, como veremos más adelante, serán la URL del adaptador, el nombre del repositorio y su usuario (en accesos remotos) y el hash del blob (fichero) a acceder.
3.3.2.2.5.
Diagrama de secuencia para “Sincronizar”
Git-commits o git-file
:Git_tree
Sincronizar(señal)
Sincronizar(señal)
Figura 3.3.25 105
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Los gadgets git-commits o git-file le envían una señal de sincronización a git-tree. Esta puede ser “bloquear” o “desbloquear”. Una vez recibida, git-tree se bloquea o desbloquea respectivamente.
3.3.2.2.6. Diagrama de secuencia para “Modificar Tamaño”
:Git_tree
EzWeb
cambio_tamaño(altura, anchura)
modificar_interfaz()
Figura 3.3.26 El usuario modifica el tamaño del gadget, señal que intercepta EzWeb y envía mediante las variables de contexto (altura, anchura) a git_tree. Éste los recibe y cambia el interfaz de usuario acorde a lo recibido.
106
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.2.3.
Implementación
3.3.2.3.1.
Clases
Al igual que git_file, git_tree solo posee una única clase, la clase tree. Está compuesta de varios métodos y atributos, que describimos en el diagrama de clases. A partir de este diagrama, se explicarán por cada caso de uso, qué métodos y atributos participan y cual es su funcionalidad. T re e + lo ck + h e a d e r_ w id th _ o ffse t + re p o sito ry + tre e + u rl + is_ co n fig u re d + C h a n g e D ir + g ith u b + sh o w e d _ tre e + id e n t + p id + a lte rn a tive s
d T re e
+ slo tT re e + slo tR e p o sito ry + slo tU R L + slo tS yn c + e ve n tR e p o sito ry + e ve n tF ile + e ve n tU R L + e ve n tS yn c + sa ve d _ re p o sito ry + sa ve d _ u rl + sa ve d _ tre e + m a in A lte rn a tive
+ in it() + cre a te U se rIn te rfa ce () + re p a in t() + lo a d in g (e n a b le ) + C o n fig W a it(e n a b le ) + sa ve () + re sto re () + re se t_ tre e () + g e tT re e () + d isp la yT re e (re sp ) + b u ild _ tre e (re sp _ jso n , lo ca l_ p id ) + d isp la yE rro r() + d isp la yE xce p tio n () + se tU R L (m sg ) + se tR e p o sito ry (m sg ) + se tT re e (m sg ) + S e n d _ S yn () + S e n d _ F in () + se tS yn c (m sg ) + E xp a n d T re e (tre e _ id , lo ca l_ p id ) + S e n d _ file (b lo b _ id , file n a m e )
+ fo ld e rL in ks + u se S ta tu sT e xt + u se C o o kie s
1 :1
+ a d d (p a re n t_ n o d e , n o d e , la b e l)
Figura 3.3.27
Sin embargo, en el diagrama aparece otra clase, dtree, esta es una librería externa que nos ayudará a “pintar” el interfaz. Esta clase ha tenido que ser modificada para que en cada nodo del árbol que sea un directorio, se instale un pequeño trozo de código que nos permita expandir el árbol.
107
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Se ha tenido que optar por expandir el árbol en cada nodo, en vez de obtener la información del árbol completo porque en fase de pruebas se descubrieron repositorios tan sumamente grandes, que intentar obtener los datos de su árbol completo puede tardar minutos. Con esta implementación, se reduce a un segundo o menos la obtención del árbol inicial y un segundo o menos cada vez que queramos expandirlo (ver el contenido de un subdirectorio). Como la clase dtree es externa, no se describirá en el diagrama de clases todos su métodos y atributos, sólo los relevantes para explicar la implementación y los que hayan sido modificados para la realización del proyecto.
3.3.2.3.2.
3.3.2.3.2.1.
Métodos por caso de uso
Iniciar_gadget
Método
Nombre
Atributos
Parámetros
MET. 1
Init
Alternatives, mainAlternative, eventSync, eventRepository, eventURL, eventFile, slotTree, slotRepository, slotURL, saved_repository, saved_url, saved_tree, showed_tree, ident, pid, folderlinks, useStatusText, useCookies
-
MET. 2
Restore
saved_repository, saved_tree, saved_url, repository, github, url, tree, is_configured
-
MET. 3
createUserInterface
Header_width_offset, is_configured, mainAlternative
-
MET. 4
ConfigWait
-
Tabla 3.3.5
108
enable
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 1 – Init Es el primero que se ejecuta cuando se inicia el gadget. Por ello, su labor es inicializar variables que hagan falta a lo largo de la ejecución. Las variables más importantes que inicializa son las que utiliza la plataforma EzWeb y las necesarias para crear el árbol con la clase de dtree:
eventSync: La variable de sincronización con git-commits, hay que indicarle a EzWeb que la asocie con la descrita en el template (XML) eventFile: Sirve para enviarle a git_file el hash del fichero que el usuario desea visualizar. eventURL: Sirve para enviarle a git_file la URL del adaptador, cuando el usuario desea visualizar un fichero. eventRepository: Sirve para enviarle a git_file el nombre del repositorio que le debe indicar al adaptador para obtener ficheros. En caso de acceso a github, además se incluirá el nombre de usuario de github del dueño del repositorio. slotTree: Variable para recibir datos de git-commits, se ha de ligar con un manejador, en este caso setTree(). Cada vez que su valor sea modificado, EzWeb lanzará el manejador. slotRepository: Variable para recibir datos de git-commits, se liga con setRepository(), de la misma forma que la anterior. slotURL: Variable para recibir datos de git-commits, al igual que las dos anteriores, se liga con su manejador setURL(). saved_repository: Variable para almacenar datos entre sesiones. Hay que asociarla a la variable creada en el template (XML) con este propósito para que EzWeb la reconozca. Almacena el nombre del repositorio a acceder. saved_url: Al igual que la anterior, se declara para que EzWeb la reconozca, alberga la URL del adaptador (API). saved_file: Como sus dos antecesoras, se asocia a su declaración en el template. En este caso guarda el hash SHA1 del blob (fichero) accedido.
109
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
showed_tree: Contenedor para albergar la parte del interfaz gráfico que se corresponde con el árbol. Para crearse, inicializa una instancia de la clase dtree. ident: Varible utilizada por dtree para saber cual es el nodo padre al que se está insertando. Inicialmente, toma el valor 1. pid: Identificador del nodo actual del árbol. Inicialmente toma el valor 0. folderlinks: Variable de configuración de la clase dtree para mostrar el árbol. Su cometido es indicar que los directorios deben contener un enlace (para poder se expandidos). useStatusText: Variable de configuración de la clase dtree para mostrar el árbol. Indica si se debe mostrar en el navegador texto en cada link. useCookies: Variable de configuración de la clase dtree para mostrar el árbol. Indica si se deben utilizar cookies del navegador para albergar el estado del árbol. Una vez inicializadas las variables, crea el árbol mediante el método add(parent_node, node, label) de dtree. El nodo raíz, que es el primero que se crea y es el que añade init(), consiste en parent_node=0 porque no tiene padre, node=-1 para indicar que es la raíz y label=Repository Tree, que será el nombre del árbol y aparecerá en el interfaz de usuario.
Posteriormente crea el contenedor para el interfaz de usuario utilizando los atributos alternatives y mainAlternative. A continuación llama al método restore() que cargará los datos almacenados de sesiones anteriores, lanza createUserInterface() para crear el interfaz en sí y por último ejecuta repaint() para redimensionar el interfaz de usuario al tamaño actual del gadget.
MET. 2 – Restore Es el encargado de cargar los datos de la sesión anterior. Gracias a que init ha inicializado las variables saved_repository, saved_tree y saved_url, el método puede utilizarlas para su propósito.
110
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Primero comprueba que estas variables contentan información, si no la contienen, finaliza su ejecución (lo que significará que el gadget no está configurado). Si contienen información, carga todos los datos y rellena los siguientes atributos:
repository: Le asignará el valor de saved_repository. En el caso de acceso a github almacenará el usuario del repositorio y su nombre, con el formato user;repository. Si por el contrario el acceso es local, sencillamente almacenará el nombre del repositorio. Para discernir entre ambos, basta con que compruebe que en la información almacenada está el carácter “;”. url: Le asignará el valor prorpocionado por saved_url. Esta variable almacena la dirección URL del adaptador (API). tree: Le asignará el valor de saved_tree. Esta última almacena el hash SHA1 del árbol a acceder. Una vez cargadas las variables finaliza su ejecución.
MET. 3 – createUserInterface Los detalles de la implementación del interfaz gráfico quedan para una sección posterior. A grandes rasgos, se crea el interfaz de usuario y se almacena en el atributo mainAlternative. Lo importante en este apartado es describir la parte lógica de la solución. En este caso, tras crear el interfaz gráfico, createUserInterface comprueba si el gadget está configurado mediante el atributo is_configured. De estar configurado, restore() le habría asignado el valor true. Si está configurado, se llama a getTree(), para que procese la petición al adaptador. Si no está configurado, se ejecuta ConfigWait() que deja el gadget bloqueado a la espera de la recepción de un mensaje por parte de git-commits.
111
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET. 4 – ConfigWait Tiene un parámetro de entrada enable. Es una variable booleana, con lo que puede tomar los valores:
true: Desactiva el interfaz de usuario, dejando al gadget bloqueado a la espera de la llegada de la configuración del sistema mostrando un mensaje a pantalla completa. false: Activa el interfaz de usuario, quitando el mensaje.
3.3.2.3.2.2. Mostrar_arbol Método
Nombre
Atributos
MET. 5
getTree
github, repository, url, tree, lock
-
MET. 6
reset_tree
showed_tree, ident, pid, folderlinks, useStatusText, useCookies
-
MET. 7
build_tree
showed_tree, ident
resp_json, local_pid
MET. 8
displayTree
ChangeDir, lock, pid
resp
MET. 9
displayError
-
-
MET. 10
displayException
-
-
MET. 11
setURL
url
msg
MET. 12
setRepository
repository, github
msg
MET. 13
setTree
tree, is_configured
msg
MET. 14
Send_Syn
eventSync
-
MET. 15
Send_Fin
eventSync
-
MET. 16
loading
-
MET. 17
save
saved_url, saved_repository, saved_tree
Tabla 3.3.6 112
Parámetros
Enable
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 5 – getTree
Se encarga de preparar la llamada al adaptador. Primero envía la señal de sincronización a git-commits para que se bloquee mediante Send_Syn(). A continuación muestra la ventana de “cargado” para bloquear la interacción con el usuario mediante loading(true). Pone la variable lock12 a true y realiza la llamada al adaptador según sea el acceso local o a github, lo cual expresa el atributo github. Si la petición es a un repositorio de github, se utilizará el atributo repository para obtener el nombre de usuario y el nombre del repositorio (separados por ;). Con estos datos más la url del adaptador y el árbol al que se desea acceder (atributo tree) se realiza la llamada. Si por el contrario, la petición era local, el procedimiento es el mismo solo que no nos hará falta el nombre de usuario. Para realizar la petición, invoca el método de EzWeb sendGet(url, successHandler, errorHandler, exceptionHandler), al que hay que pasarle como argumento la URL a la que va dirigida la petición, el manejador si la petición va correctamente (successHandler) y los de error y excepción (errorHandler y exceptionHandler respectivamente). En el caso de getTree, los manejadores son:
SuccessHandler: displayTree(resp) ErrorHandler: displayError() ExceptionHandler: displayException()
El método finaliza su ejecución al hacer la petición. Cuando EzWeb reciba respuesta, reanudará la ejecución del gadget según si ha sido procesada correctamente o no.
12
Lock sirve para designar dos niveles de prioridad en los bloqueos. Si lock está a true otro gadget no lo puede desbloquear. De esta forma los autobloqueos no pueden ser desbloqueados por señales externas.
113
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET. 6 – reset_tree Su trabajo es reiniciar el árbol. Es decir, dejarlo como lo dejaba el método init() para rellenarlo con nueva información. Para ello, crea un nuevo objeto de la clase dtree en el atributo showed_tree, pisando la información que hubiera anteriormente. Una vez echo esto, coloca los valores por defecto de la configuración de dtree (folderlinks, useStatusText, useCookies) y añade el nodo raíz al igual que el método init.
MET. 7 – build_tree Este método construye el árbol que visualizamos por pantalla partiendo de la respuesta del adaptador. Sus argumentos son:
resp_json: Es la respuesta del adaptador (API) en formato JSON. Con tiene todos los nodos del nivel actual del árbol. local_pid: Es el identificador del árbol a construir.
Para cumplir su cometido, recorre la lista de resp_json y genera una estructura de datos que le enviamos a la clase dtree para que la convierta en lo que se aprecia en el interfaz gráfico. Al recorrer la lista, comprueba de qué tipo es cada nodo. Los nodos pueden ser árboles (subdirectorios) o blobs (ficheros). Si el nodo es de tipo árbol, se llamará al objeto dtree contenido en el atributo showed_tree con el método add que añadirá un nuevo nodo al árbol. En este caso, al tratarse de un subdirectorio, se le indicará este hecho y los iconos que debe utilizar para la carpeta abierta y cerrada. Si el nodo es un fichero, también se llamara al método add, pero en este caso con diferentes argumentos para que se incruste directamente el fichero en el árbol. Para realizar ambas llamadas, se utilizan los atrbiutos ident (identificador del nodo) y local_pid (identificador del árbol).
114
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 8 – displayTree Es el método que se ejecuta cuando el adaptador devuelve una respuesta favorable a la petición. Recibe como argumento dicha respuesta, con el nombre resp_json en formato JSON. Lo primero que hace, es guardar la configuración del gadget, ya que la llamada ha sido favorable. Posteriormente, llama a build_tree pasándole como argumento la resp_json para que construya los nodos del árbol en el interfaz de usuario. Una vez hecho esto, se comprueba si la petición era por expandir un subdirectorio o por ser un árbol inicial. Esto lo controla el atributo ChangeDir, es necesario saber esto para incrustar el nuevo árbol obtenido en la raíz o descolgando (subdirectorio) a partir de otro. Por último, realiza las tareas de sincronismo, desbloqueando al gadget con loading(false), desactivando el atributo lock (false) y enviando la señal de desbloqueo a git-commits (mediante Send_Fin()).
MET. 9 – displayError Desbloquea el gadget mediante loading(false) y lock=false, desbloquea al gadget git-commits con la llamada Send_Fin() y muestra un mensaje por pantalla indicando que ha habido un error durante la petición al adaptador. MET. 10 – displayException Igual que el método anterior, solo que se ejecuta en el caso de haber alguna excepción en el código (por ejemplo, al evaluar la respuesta del adaptador).
115
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET. 11 – setURL Gracias a que el método 1, init, ha configurado las variables “slot”, cuando EzWeb recibe medinate wiring, que otro gadget le ha enviado información a git-tree, ejecuta esta función. En este caso cuando se envía información a la variable slotURL. Recibe como parámetro msg, que contiene la información enviada al slotURL. La almacena en el atributo url. MET. 12 – setRepository Al igual que la anterior, EzWeb lanza el método cuando se modifica la variable slotRepository, indicando el valor en el parámetro msg. Según la información recibida, almacena las variables github y repository. Puede recibir 2 tipos de mensajes:
User;repository: Este tipo de mensaje hace referencia al acceso a github, porque se necesitan los dos datos para acceder a los repositorios (usuario y nombre del repositorio). Por tanto, asigna true al atributo github y almacena esta cadena en repository. Repository: Si sólo recibe el nombre del repositorio, se trata de acceso local, con lo que asigna false a github y rellena repository con esta cadena.
MET. 13 – setTree De nuevo, este método es invocado por EzWeb cuando se modifica la variable slotTree, indicando su valor en el parámetro msg. En ella se recibe el hash SHA1 del árbol al que se desea acceder. Este valor se guarda en el atributo tree. Una vez almacenado el árbol, este método es el encargado de iniciar la llamada al adaptador y de guardar los datos. Para ello, primero realiza una llamada al método save() y posteriormente a getFile().
116
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 14 – Send_Syn Asigna el valor “syn” al atributo eventSync. Al haber sido inicializada por init, EzWeb detecta la modificación y envía su valor al gadget conectado al evento. En el sistema planteado, el gadget receptor será git-commits, que se bloqueará al recibirlo. MET. 15 – Send_Fin Asigna el valor “fin” al atributo eventSync. Funciona igual que el método anterior, solo que el resultado en este caso será que gitcommits se desbloqueará. MET. 16 – Loading Recibe el parámetro enable. Es un parámetro de tipo boolean, si está a true, bloquea el interfaz de usuario mostrando un mensaje a pantalla completa indicando que le gadget está a la espera de recibir una petición del adaptador. Si por el contraro está a false, desbloquea el interfaz eliminando dicho mensaje. MET. 17 – save Cuando setTree() recibe el árbol que se desea visualizar, se llama a save() para que guarde los parámetros de la petición para futuras sesiones. De esta forma, utilizando las variables de preferencia de EzWeb, el gadget git-tree almacena la URL del adaptador, el nombre del repositorio y el hash SHA1 del árbol en los atributos saved_url, saved_repository y saved_tree respectivamente.
3.3.2.3.2.3. Expandir_arbol
Método
Nombre
Atributos
Parámetros
MET. 18
ExpandTree
Lock, pid, ChangeDir, github
Tree_id, local_pid
Tabla 3.3.7
117
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET.18 – ExpandTree Este método se invoca cuando el usuario despliega un subdirectorio del árbol. Es llamado por la clase modificada dtree y sus parámetros son:
Tree_id: El identificador SHA1 del subdirectorio (árbol) a acceder. Local_pid: Es el identificador del árbol que se está manejando.
Con estos datos, se realiza el mismo procedimiento que getTree con la siguiente salvedad:
ChangeDir: Se le asigna el valor true para que displayTree sepa que se trata de un acceso a subdirectorio, con lo que colocará los nuevos datos recibidos en la posición de la carpeta desplegada.
3.3.2.3.2.4.
Enviar_fichero
Método
Nombre
Atributos
Parámetros
MET. 19
Send_file
eventRepository, eventURL, eventFile
blob_id, filename
Tabla 3.3.8
MET. 19 - Send_file Cuando el usuario selecciona un fichero para su visualización, entra en ejecución este método. Se encarga de asignarle valores a las siguientes variables (atributos):
118
eventRepository: Se le asigna el nombre del repositorio a acceder (accesos locales) o el nombre del repositorio y el de usuario en accesos remotos (a github). En cuanto se modifica su valor, EzWeb captura el evento y envía la variable mediante wiring a gitfile.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
eventURL: Se le asigna la URL del adaptador (API), al igual que la anterior EzWeb la transporta a git-file. eventFile: Se le asigna el hash del fichero a acceder y el nombre del fichero. EzWeb lo envía a git-file 3.3.2.3.2.5.
Sincronizar
Método
Nombre
MET. 20
setSync
Atributos
Parámetros -
Msg
Tabla 3.3.9 MET. 20 – setSync Este método se activa cuando EzWeb modifica el atributo slotSync, al ser su manejador configurado en el método init. Recibe como parámetro “msg”, que puede tomar los valores:
SYN: Sincronizar, bloquea el gadget a la espera de su desbloqueo. Además, repite la sincronización hacia git-commits mediante Send_syn(). FIN: Fin de la sincronización, desbloquea el gadget. Además, repite la sincronización hacia git-commits mediante Send_fin().
3.3.2.3.2.6. Modificar_tamaño
Método
Nombre
Atributos
MET. 21
repaint
header_width_offset
Parámetros -
Tabla 3.3.10
119
[PROYECTO FINAL DE CARRERA]
Mario Mira Boronat
MET. 21 – repaint Se ejecuta cada vez que se modifican las variables de contexto del gadget. En este caso height y width. Es decir, cuando el usuario cambia el tamaño del gadget, repaint se encarga de redimensionar utilizando width y height el interfaz de usuario. El atributo header_width_offset, es la única constante que se utiliza para controlar el aspecto resultante de la redimensión.
3.3.2.3.3.
Template
Se describe en este apartado, las partes importantes del fichero XML (template) del gadget. Ellas son, las que configuran variables con EzWeb para luego poder utilizarlas en su implementación. De todo el template lo más importante son las variables de Wiring, que nos permiten comunicarnos con otros gadgets. En este caso, se necesita comunicar con los gadgets git-commits y git-file. De gitcommits recibiremos datos a mostrar por pantalla (en este caso árboles), mientras que git-file lo utilizaremos como interfaz para mostrar los ficheros del árbol que el usuario desee visualizar. slotFile
eventFile
slotRepository
eventRepository
slotTree
eventTree
slotRepository
eventRepository
Git-tree
Git-file
Git-commits
slotURL
eventURL
slotURL
eventURL
eventSync
slotSync
eventSync
slotSync
Figura 3.3.28 En la figura vemos que intervienen tres gadgets (git-file, git-tree y git-commits). En este caso, nos centramos en git-tree. Git-tree le envía a git-file las variables eventFile, eventRepo y eventURL, que se corresponden con las ranuras slotFile, slotRepository y slotURL.
120
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
eventFile/slotFile: se encarga de transportar el hash SHA1 del fichero al que se debe acceder. Un hash SHA1 es una cadena alfanumérica de X caracteres. eventRepo/slotRepo: transporta el nombre del repositorio a acceder. Si el acceso es local el dato es un string con el nombre. Si el acceso es a GitHub, se envía el nombre del repositorio y el nombre del usuario asociado, con el formato “usuario;nombre”. El carácter “;” que no se va a encontrar en el nombre de un repositorio, es el que ocasionará que git-file sepa que debe hacer el acceso a GitHub. eventURL/slotURL: envía la dirección URL de la localización de la API REST que escuchará las peticiones del gadget. En segundo caso, el sentido de git-file a git-tree, encontramos una única variable, la variable de sincronización. eventSync/slotSync: Cada vez que git-file hace una petición asíncrona a la API (todas las peticiones son asíncronas, al utilizar la tecnología AJAX), envía una señal (un carácter) por este canal para bloquar a gittree y se bloquea a sí mismo. Cuando la API ofrece respuesta, el gadget se desbloquea y envía la señal de desbloqueo a git-tree.
Entre git-tree y git-commits: eventTree/slotTree: se encarga de transportar el hash SHA1 del árbol al que se desea acceder. El resto de canales, sirven el mimo cometido que entre git-file y git-tree.
121
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.2.3.3.1. Propiedades Propiedades
<Platform.StateProperties> <Property name=”saved_tree” type=”text” label=”saved_tree” description=”Tree saved for the next sesion”/> <Property name=”saved_repository” type=”text” label=”saved_repository” description=”Repository saved for next sesion”/> <Property name=”saved_url” type=”text” label=”saved_url” description=”Django API’s URL for next sesion”/> </Platform.StateProperties>
Git-tree.xml
Se han resaltado en negrita los tags que del fichero. Se procede ahora describir los campos:
122
Platform.StateProperties: Se pueden instanciar tantas como se quiera, en este caso se usan tres: o Saved_tree: Almacenará el hash SHA1 del árbol que se está visualizando para futuras sesiones de uso. o Saved_repository: Según si estamos visualizando repositorios en local o en GitHub se almacenará una información u otra. En el caso local, se guarda el nombre del repositorio visualizado para futuras sesiones. En el caso del acceso a GitHub, se guarda tanto el nombre del repositorio como el nombre de usuario de github asociado al mismo. o Saved_url: Se guarda en este campo la URL de la API a la que se tienen que lanzar las peticiones para obtener los datos de los ficheros a visualizar.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.2.3.3.2. Wiring Wiring
<Platform.Wiring> <Slot name=”slotTree” type=”text” label=”tree” friendcode=”sha1tree”/> <Slot name=”slotRepository” type=”text” label=”repository” friendcode=”repository”/> <Slot name=”slotURL” type=”text” label=”url” friendcode=”url”/> <Slot name=”slotSync” type=”text” label=”sync” friendcode=”sync”/> <Event name=”eventRepository” type=”text” label=”repository” friendcode=”repository”/> <Event name=”eventURL” type=”text” label=”url” friendcode=”url”/> <Event name=”eventFile” type=”text” label=”file” friendcode=”sha1file”/> <Event name=”eventSync” type=”text” label=”sync” friendcode=”sync”/> </Platform.Wiring> Git-tree.xml
Platform.Wiring: Para comunicarse con otros gadgets, se utilizan las siguientes variables, que dividimos en slots y events. o Slots: slotTree: En esta ranura se recibirá el hash SHA1 referente al árbol que se desea visualizar en git-tree. slotRepository: Se recibirá el nombre del repositorio en el caso de acceso local y el nombre del repositorio más el nombre de usuario de GitHub, en el caso de accesos remotos.
123
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
slotURL: Aquí se recibe la URL de la API a la que hacer las peticiones de información. o Events: eventFile: Envía el fichero que selecciona el usuario a git-file para que lo visualice. eventRepository: Envía el nombre del repositorio (accesos locales) o el nombre del repositorio y su usuario (accesos github) a git-tree. eventURL: Envía a git-tree la URL del adaptador (API) eventSync: Este evento se utiliza para avisar a otros gadgets que las peticiones a la API han finalizado (para sincronizarse).
3.3.2.3.3.3. Contexto Contexto
<Platform.Context> <Context name=”user” type=”text” concept=”user_name”/> <GadgetContext name=”height” type=”text” concept=”heightInPixels”/> <GadgetContext name=”lockStatus” type=”text” concept=”lockStatus”/> </Platform.Context>
Git-tree.xml
124
Platform.Context: o User: Nombre de usuario que esta utilizando la plataforma EzWeb. o Height: Altura del gadget. Para redimensionar el interfaz gráfico.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
o LockStatus: Indica el estado de bloqueo del gadget. Lo utiliza la librería extendida de EzWeb.
3.3.2.3.4.
Interfaz de usuario
Por último, se describe en este apartado el aspecto resultante del gadget, así como los métodos involucrados en la modificación del mismo. Git-tree consta de cuatro estados del interfaz de usuario. El interfaz principal, dos mensajes de bloqueo (esperar configuración y esperar petición de la API) y los mensajes de error. Se presentan a continuación capturas de pantalla de cada uno de ellos.
Figura 3.3.29
125
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
La figura 3.3.29 muestra el interfaz principal del gadget.
En 1 podemos observar el hash del árbol que se está mostrando. En 2 se muestra el contenido del árbol
Figura 3.3.30 Este caso se corresponde a la invocación del método loading, que bloquea el gadget hasta que se reciba respuesta del adaptador.
126
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Figura 3.3.31
Este mensaje nos aparece cuando se instancia el gadget por primera vez y no está configurado. Desaparece en cuanto git-commits le envía la configuración mediante wiring.
Figura 3.3.32
127
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Por último, la venta de los mensajes de error. El diseño que muestra es el que nos proporciona la librería extendida de EzWeb.
Los métodos que afectan al interfaz de usuario son: Método
Nombre
Descripción
MET. 1
init
Crea el contenedor del árbol e inicializa su nodo raíz. El nodo raíz es el que tiene el texto “Repository tree”.
MET. 3
createUserInterface
Crea todas las capas y elementos del interfaz principal (fig X)
MET. 4
ConfigWait
Muestra el mensaje de la figura X
MET. 7
build_tree
Rellena el contenido del árbol en el interfaz principal (Número 2 en figura X). Para ello utiliza la librería dtree.
MET. 9
displayError
Muestra un mensaje como el de la figura X pero con el texto asociado al error ocurrido.
MET. 10
displayException
Muestra un mensaje como el de la figura X pero con el texto asociado a la excepción generada.
MET. 16
Loading
Muestra el mensaje de la figura X
MET. 21
Repaint
Redimensiona 1 en la figura X según los nuevos valores
Tabla 3.3.11
128
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3. Git-commits 3.3.3.1.
Captura de Requisitos
El objetivo de este gadget es mostrar la información principal de un repositorio. Este repositoiro puede ser local o remoto (github). En ambos casos, se muestra la misma información, la cual es: El número y nombre de ramas del repositorio, pudiendo cambiar entre una y otra; la lista de todos los commits del repositorio y por cada commit, toda su información (autor, committer, mensaje de información, fechas…). Además debe ofrecer opciones de configuración y cada vez que el usuario seleccione un commit, debe enviar la información de su árbol de ficheros asociado a git-tree. Adicionalmente, debe aceptar peticiones de visualización de repositorio de github-browser, el cual le proporcionará el nombre de usuario y repositorio del mismo. 3.3.3.1.1.
Actores
Usuario Es la persona que utiliza el gadget. Sus tareas serán varias. Deberá en primer lugar, configurar el gadget para acceder al repositorio. En segundo lugar deberá elegir la rama del repositorio que quiere visualizar y una vez visualizada la rama, navegar por el repositorio para escoger un commit a detallar. Adaptador Como con sus antecesores, es la API REST que proporciona los datos que el gadget solicita, en este caso, esta información vendrá dividida en varias peticiones. Deberá atender peticiones de comprobación de la URL, petición del listado de repositorios, listado de ramas y listado de commits con su información asociada. Github-browser Es otro gadget del sistema, cuyo cometido en el ámbito que nos interesa es enviar información sobre a qué repositorio se debe acceder,
129
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
ya que el usuario lo desea visualizar. A su vez, se realizarán tareas de sincronismo con él. Git-tree Es otro gadget del sistema, su labor es mostrar el árbol asociado a un determiado commit que le enviemos mediante wiring. A su vez, se realizarán tareas de sincronismo con él. EzWeb Cada vez que el usuario modifique el tamaño del gadget, EzWeb le indicará a través de las variables de contexto los nuevos valores.
3.3.3.1.2.
Identificación y descripción de los casos de uso
Iniciar gadget: El usuario agregará a la plataforma EzWeb el gadget o iniciará la plataforma en su navegador con el gadget en su workspace. En este caso, el gadget comprobará si está configurado. De no estarlo, pasará a configurar gadget. De estarlo, pasará a mostrar repositorio. Configurar gadget: Se iniciará de dos formas, bien el usuario manualmente accede a configurar (o reconfigurar) o bien el gadget se inicia por primera vez y no está configurado. El gadget, solicita al usuario por fases todos los datos necesarios para iniciar el sistema. En primer lugar, solicitará la URL del adaptador. Una vez introducida, comprobará si es válida, si no lo es mostrará un mensaje de error. De ser válida, pasará a la siguiente fase y le preguntará el tipo de acceso que desea utilizar (local o github). Si se seleciona acceso local, el gadget pedirá al adaptador el listado de repositorios locales disponibles, de los cuales el usuario seleccionará uno y guardará la configuración, pasando a mostrar repositorio. Si por el contrario, se selecciona acceso a github, se le solicitará al usuario el nombre de usuario y nombre de repositorio de github del repositorio git al que se desea acceder. Una vez introducido, el usuario guardará la configuración y el gadget pasará a mostrar repositorio. Mostrar repositorio: Se puede iniciar de tres formas. Bien a raíz de iniciar el gadget ya configurado, tras configurar (y reconfigurar) el
130
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
gadget o recibiendo la configuración de github-browser. Independientemente del método utilizado, su procedimiento no varía. En primer lugar, obtendrá la información de ramas del repositorio. Una vez obtenida, escogerá la primera rama y solicitará la información de commits de esa rama. Junto a la información del listado de commits, se recibe la información detallada de cada uno. Para no abrumar al usuario, el listado de commits se dividirá en páginas. Por tanto, se muestra la primera página de este listado (5 commits) y la información detallada del primero (autor, committer, ID‟s y mensaje). A su vez, se enviará a git-tree la configuración del repositorio a acceder y el identificador (hash) del árbol asociado al primer commit. Si en cualquiera de estos pasos, se produce algún error, se notificará al usuario por pantalla, abortando la ejecución del caso de uso. En todos los accesos al adaptador, se realizarán tareas de sincronismo con github-browser. Cambiar rama: Una vez cargado el repositorio, el usuario podrá cambiar de rama (si el repositorio tiene más de una rama). Cuando cambie de rama, se solicitará el listado de commits al adaptador y, al igual que en mostrar commits, se mostrará dicho listado paginado (de 5 en 5), la información detallada del primero y se enviarán sus datos a git-tree para que muestre el árbol asociado. En el acceso al adaptador se realizarán tareas de sincronismo con github-browser. Seleccionar commit: El usuario puede seleccionar otro commit del listado de commits mostrado. Cuando lo haga, primero se mostrará la información detallada del mismo en el gadget y a continuación se enviará la información de configuración e ID del árbol asociado a gittree. Cambiar página: El usuario puede cambiar de página del listado de commits. Si el acceso es a github, el listado completo de repositorios estará ya almacenado en el sistema, con lo que se muestran los 5 siguientes y se envía a git-tree su información asociada. Por el contrario, si el acceso es local, la información no estará paginada, con lo que el gadget debe hacer una nueva petición al adaptador solicitando la siguiente página, mostrándola por pantalla y enviando a git-tree el árbol
131
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
a mostrar. En el acceso al adaptador se realizarán tareas de sincronismo con github-browser. Sincronizar: Git-tree puede enviar una señal de bloqueo a git-commits. Lo hará cuando acceda al adaptador, para evitar recibir nuevas peticiones por parte de este último. Cuando la señal llega, el gadget debe bloquearse hasta recibir la señal de desbloqueo. Modificar tamaño: El usuario modificará el tamaño del gadget en su navegador, por tanto, EzWeb le comunicará los nuevos valores al gadget. El gadget volverá a pintar el interfaz de usuario acomodándose a estos nuevos valores. Se observa la interacción entre los actores y los casos de uso en el siguiente diagrama de casos de uso.
iniciador
Mostrar_repositorio iniciador
Github-browser API
i n i n i ci a ic do ia r do r
ini
iniciador
ci a
do
r
Iniciar_gadget
Usuario
Configurar_gadget
Git-tree
iniciador ini ci a do r
Cambiar_rama
in ic ia do
Seleccionar_commit
r
Cambiar_pagina ini
ci a
Git-tree
do
r
Sincronizar
inicia
dor
Modificar_tamaño
EzWeb
Figura 3.3.33 132
Github-browser
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
El usuario es el encargado de iniciar todo el sistema. Iniciar_gadget comprobará la configuración del sistema y según ésta, llamará a Configurar_gadget si no lo está o a Mostrar_repositorio si lo está. Configurar_gadget será iniciado por Iniciar_gadget si el gadget no está configurado o por el usuario si desea reconfigurar el gadget. Necesitará comunicarse con la API para comprobar la URL introducida y obtener el listado de repositorios locales. Mostrar_repositorio será iniciado por Iniciar_gadget, Configurar_gadget (una vez configurado) o github-browser cuando le envíe un repositorio a acceder. Para ello, tendrá que comunicarse con la API para obtener información, con github-browser para bloquearlo mientras realiza los accesos y con git-tree para bloquearlo durante los accesos y enviarle los árboles que debe mostrar. Cambiar_rama lo iniciará el usuario cuando desee realizar esta operación. Se comunicará con la API para obtener datos, con githubbrowser para sincronismo y con git-tree para sincronismo y envío de datos. Seleccionar_commit lo inciará el usuario cuando desee visualizar otro commit. No necesita comunicarse con la API, pero sí con git-tree y github-browser para sincronismo y envío de datos. Cambiar_página lo inciará el usuario cuando desee visualizar la siguiente página de commits. Al igual que cambiar_rama, se comunicará con la API y con los otros gadgets para envío/recepción de datos y sincronismo. Por último, sincronizar bloqueará/desbloqueará el gadget cuando git-tree lo solicite y modificar_tamaño se ejecutará cuando EzWeb avise de un cambio de tamaño en el gadget.
133
Mario Mira Boronat
3.3.3.1.3.
[PROYECTO FINAL DE CARRERA]
Diagramas de contexto
Para describir de forma más detallada el comportamiento de cada caso de uso, recurrimos a los diagramas de contexto.
3.3.3.1.3.1. Iniciar_gadget
Inicio sistema Comprobar configuración
No configurado
Mostrar interfaz de configuración
Configurado
Mostrar interfaz del repositorio
Configurado
Salir
Figura 3.3.34 Iniciar_gadget comprueba si está configurado el gadget. Si no lo está, muestra el interfaz de configuración, del que se saldrá configurado para mostrar el interfaz del repositorio. Si ya lo estaba, lo mostrará directamente.
134
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.1.3.2. Configurar_gadget
configurar ok
Solicitar URL del adaptador (API)
Mostrar mensaje de error
URL
ok error
Bloquear
Desbloquear
URL válida
Desbloquear
ok
Seleccionar tipo de acceso
local
Petición listado de repositorios locales a la API
ok error
repositorio
github
ok Mostrar mensaje de error
Guardar configuración
Salir
error
Introducir usuario y repositorio de github
Usuario y repositorio
Figura 3.3.35
En primer lugar, se solicitará al usuario que ingrese la URL del adaptador (API) para usar durante la ejecución. Una vez introducida, el gadget se bloqueará mientras se realiza la petición de comprobación de
135
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
URL al adaptador. Si la URL está mal introducida, el adaptador no contestará, o contestará con una información incorrecta. En este caso, se desbloqueará y se mostrará un mensaje de error al usuario. Si la ingresa correctamente, el gadget solicitará la selección del tipo de acceso por parte del usuario. Llegados a este punto, la ejecución se divide en dos ramas. Si el usuario selecciona acceso local, se le pedirá a la API el listado de repositorios albergados en local, el cual se mostrará en un desplegable. De todos ellos, el usuario escogerá el que quiera ver y guardará la configuración, pasando a mostrar el repositorio. Si por el contrario, el usuario selecciona acceso a github, la información necesitada es diferente. Se precisa del nombre de usuario y repositorio de github. Una vez ingresados, se pasará a mostrar el repositorio. Si ocurre algún error en estos dos hilos de ejecución, se mostrará un mensaje de error al usuario para que ingrese de nuevo los datos.
136
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.1.3.3.
Mostrar_repositorio Mostrar repositorio Petici贸n de ramas del repositorio al adaptador ok
Bloquear
error
Desbloquear
Lista ramas
ok
Mostrar mensaje de error
Desbloquear
ok
Salir
Mostrar ramas
ok
Petici贸n de commits del repositorio al adaptador ok
Bloquear
error
Desbloquear
Lista commits
Desbloquear
ok
ok
Mostrar mensaje de error
Salir
Mostrar commits
ok
Enviar configuraci贸n y 谩rbol a git-tree
Figura 3.3.36 Salir
137
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
La primera solicitud que se le hará al adaptador será la de obtener las ramas (branches) del repositorio. Como toda petición a la API, involucra que el gadget se bloquee hasta obtener la respuesta y envíe la señal de bloqueo a github-browser para que haga lo mismo. Cuando recibe la petición (favorable o no), se desbloquea y propaga el desbloqueo al resto de gadgets. Si la petición no es favorable (error) lo muestra por pantalla y aborta el proceso. Si es favorable, muestra por pantalla un desplegable con todas las ramas y selecciona la por defecto para seguir ejecutando. En segundo lugar, utilizando la rama por defecto, realiza la petición a la API para obtener el listado de commits de dicha rama. Al igual que la anterior petición, se bloquea, propaga el bloqueo y espera la respuesta. Sea cual sea, al recibirla se desbloquea y propaga el desbloqueo. Si la respuesta es incorrecta, muestra un mensaje por pantalla y aborta la ejecución. Si la respuesta es correcta (listado de commits) los muestra por pantalla. Por último, selecciona el primer commit por la lista y muestra sus detalles, enviando la configuración utilizada para obtener los datos y el árbol asociado a dicho commit a git-tree.
138
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.1.3.4.
Cambiar_rama rama Petición de commits del repositorio al adaptador ok
Bloquear
error
Desbloquear
Lista commits
Desbloquear
ok
ok
Mostrar mensaje de error
Salir
Mostrar commits
ok
Enviar configuración y árbol a git-tree
Salir
Figura 3.3.37
Es un caso simplificado de mostrar_repositorio. Su ejecución comienza cuando el usuario selecciona una rama del desplegable de ramas. A partir de ahí ejecuta igual que mostrar_repositorio a partir de cuando selecciona la rama por defecto.
139
Mario Mira Boronat
3.3.3.1.3.5.
[PROYECTO FINAL DE CARRERA]
Seleccionar_commit commit Mostrar información detallada para ”commit” ok
Enviar configuración y árbol a git-tree
Salir
Figura 3.3.38
Una vez un repositorio está mostrado, el usuario en cualquier momento puede seleccionar un commit para ver sus detalles. De hacerlo, se ejecuta este caso de uso, en el que se muestra en el gadget git-commits la información detallada del commit seleccionado y se envía a git-tree su árbol asociado para que obtenga sus datos y lo muestre.
140
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.1.3.6.
Cambiar_pagina página Comprobar tipo de acceso
local
github
Petición de nueva página del repositorio al adaptador ok
Bloquear
error
Desbloquear
Lista commits
Desbloquear
ok
ok
Mostrar mensaje de error
Salir
Mostrar commits
ok Enviar configuración y árbol a git-tree
Figura 3.3.39 Salir
Cuando el usuario solicita una nueva página de commits del repositorio, se siguen dos cursos de acción. En el primer caso, si el acceso es local, los commits no están cacheados, con lo que se pedirán al adaptador. Esto implica bloqueo del
141
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
gadget, propagación, espera de la respuesta, comprobación de error, desbloqueo y propagación del desbloqueo, como hemos visto en los anteriores casos de uso. Una vez obtenida la respuesta se muestra la nueva página y se envía a git-tree el primer commit de la página para que muestre el árbol asociado. En el segundo caso, acceso a github, ya se tiene en caché la lista de commits completa del repositorio, con lo que no es necesario hacer la petición a la API. Directamente se muestra la nueva página en el interfaz y se enví a git-tree el árbol del primer commit.
3.3.3.1.3.7.
Sincronizar
Petición bloqueo
Bloquear
Desbloqueo
Desbloquear
Salir
Figura 3.3.40 Cuando el gadget recibe la petición de bloqueo de git-tree se bloquea a la espera de recibir la señal de desbloqueo. Cuando la recibe, se desbloquea. Toda esta comunicación se realiza mendiante wiring.
142
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.1.3.8.
Modificar tamaño
Inicio sistema
Modificar tamaño
Salir
Figura 3.3.41 El usuario modificará el tamaño del gadget y será EzWeb el que notifique al gadget mediante las variables de contexto de este suceso, para que reajuste el interfaz de usuario.
143
Mario Mira Boronat
3.3.3.2.
[PROYECTO FINAL DE CARRERA]
Diseño
Con los requisitos mostrados anteriormente y teniendo en cuenta los actores del sistema, vamos a describir los diagramas de secuencia de cada caso de uso. En ellos, veremos la interactuación entre los componentes del diseño.
3.3.3.2.1.
Diagrama de secuencia para “Iniciar_gadget”
:Git_commits
Usuario iniciar()
[*si está configurado] mostrar_repositorio(config)
[*si no está configurado] configurar_gadget()
Figura 3.3.42 El usuario inicia el sistema. El gadget comprueba su configuración. Si está correctamente configurado, pasa a mostrar repositorio. Si no está configurado, muestra la ventana de configuración.
144
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.2.2. Diagrama de secuencia para “Configurar gadget”
:Git_commits
Usuario
:Adaptador
configurar()
url() url bloquear() test_url(url) OK
desbloquear() tipo_acceso() tipo_acceso [*si tipo_acceso=local] listado_repos() listado_repos [*si tipo_acceso=local] select_repo() repo
[*si tipo_acceso=github] datos_repo() usuario, repositorio
Figura 3.3.43 El usuario sera el encargado de configurar el gadget. Para ello, lo primero que se necesita es la URL del adaptador, por lo que se le pedirá. Una vez introducida, se comprobará si es correcta, para ello el gadget se bloquea impidiendo que el usuario modifique otros valores. Una vez resuelta la veracidad de la URL, el usuario deberá introducir el tipo de
145
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
acceso que va a realizar (local o github), por tanto, el gadget se lo solicitará. Según el tipo de acceso introducido, se opera de una manera diferente. En el caso de acceso local, se obtendrán el listado de repositorios locales disponibles en el adaptador. Una vez obtenidos, se mostrarán al usuario, el cual seleccionará el que desea visualizar. Si por el contrario, el acceso es a github, se le solicitará al usuario que introduzca el nombre del repositorio remoto y usuario asociado al que desea acceder. Una vez rellenados todos los datos, se pasará a mostrar el repositoiro.
3.3.3.2.3. Diagrama repositorio”
de
:Git_commits
Usuario
secuencia
:Adaptador
:Git_tree
mostrar_repo() bloquear()
bloquear()
get_branches(repo) lista_branches
get_commits(branch1) lista_commits
send_tree(tree, config)
desbloquear() desbloquear()
Figura 3.3.44
146
para
“Mostrar
:Github_browser
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Mostrar repositorio lo primero que hace es obtener el listado de branches (ramas) del reposiotorio a acceder. Para ello, se bloquea y bloquea a github-browser, como toda petición al adaptador. El adaptador contestará con la lista de branches del repositorio, de las cuales se usará la primera para hacer la siguiente petición. La siguiente petición es el listado de commits del repositorio, una vez el adaptador conteste con este listado y los detalles de todos los commits, se mostrarán por pantalla. A su vez, se enviará el árbol asociado al primer commit de la lista a git-tree para que lo visualice. Por último, se desbloqueará y enviará la señal de desbloqueo a github-browser, dando por finalizada la operación.
3.3.3.2.4.
Diagrama de secuencia para “Cambiar rama”
:Git_commits
Usuario
:Adaptador
:Git_tree
:Github_browser
change_branch(branch) bloquear()
bloquear()
get_commits(branch) lista_commits
send_tree(tree, config)
desbloquear() desbloquear()
Figura 3.3.45 Partiendo de un repositorio ya mostrado, el usuario en cualquier momento puede seleccionar otra rama de la lista de branches (ramas).
147
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Cuando así lo haga, pondrá en marcha el mismo mecanismo que para “mostrar repositorio”, pero en vez de con la rama por defecto, con la rama seleccionada. Para ello se bloqueará y bloqueará a github-browser realizando la petición al adaptador del listado de commits para esa rama determinada. Cuando obtenga el listado, enviará el árbol asociado al primero a git-tree, desbloqueándose y enviando el desbloqueo a githubbrowser.
3.3.3.2.5. Diagrama de secuencia para “Seleccionar commit”
Usuario
:Git_commits
:Git_tree
select_commit(commit)
mostrar_información_detallada(commit)
send_tree(tree, config)
Figura 3.3.46
Al igual que en el caso anterior, partimos del repositorio ya mostrado en pantalla. En este caso, el usuario desea ver otro commit de la lista, para ello, lo seleccionará. Esto pondrá en marcha que, primero se muestre la información por pantalla y segundo se envíe el árbol asociado a dicho commit a git-tree para que lo muestre.
148
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.2.6.
Diagrama de secuencia para “Cambiar página”
:Git_commits
Usuario
:Adaptador
:Git_tree
:Github_browser
cambiar_página(pag) [*si tipo_acceso=local] bloquear()
[*si tipo_acceso=local] bloquear()
[*si tipo_acceso=local] siguiente_página(pag) lista_commits
[*si tipo_acceso=github] mostrar_pag(pag)
send_tree(tree, config)
[*si tipo_acceso=local] desbloquear() [*si tipo_acceso=local] desbloquear()
Figura 3.3.47
Este es el caso en el que el usuario pagina con la lista de commits. Por ser engorroso mostrar todos los commits de un repositorio de golpe (pueden llegar a ser cientos), se ha optado por mostrarlos cómodamente de 5 en 5. En el caso en el que el acceso esté siendo a github, se habrán cacheado hasta un máximo de 30 commits en el gadget (github no nos permite ver más hallá de 30 commits). Por tanto, esta paginación no requerirá del acceso al adaptador y se mostrará directamente la información, enviando el árbol a git-tree del primero de la página. No obstante, en los accesos a repositorios locales, sí que podemos navegar en la lista de commits del primero al último. Por tanto, no
149
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
tenemos cacheada la lista entera en el gadget, lo que ocasiona la necesidad de realizar una petición al adaptador para obtener la siguiente página. Como en toda petición, el gadget se bloqueará y enviara el bloqueo, hará la petición y al recibir los datos se desbloqueará y enviará la señal de desbloqueo. Al igual que en el acceso a github, se enviará el árbol asociado al primer commit de la página a git-tree.
3.3.3.2.7.
Diagrama de secuencia para “Sincronizar”
:Git_commits
Git-tree Sincronizar(señal)
Sincronizar(señal)
Figura 3.3.48
El gadget git-tree le envía una señal de sincronización a gitcommits. Esta puede ser “bloquear” o “desbloquear”. Una vez recibida, git-commits se bloquea o desbloquea respectivamente.
150
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.2.8.
Diagrama de secuencia para “Modificar tamaño”
:Git_commits
EzWeb
cambio_tamaño(altura, anchura)
modificar_interfaz()
Figura 3.3.49 El usuario modifica el tamaño del gadget, señal que intercepta EzWeb y envía mediante las variables de contexto (altura, anchura) a git_tree. Éste los recibe y cambia el interfaz de usuario acorde a lo recibido.
3.3.3.3.
Implementación
3.3.3.3.1. Clases Para la implementación de este gadget se han utilizado dos clases. Es el gadget más grande del sistema, la clase git_repository hace todo el trabajo de presentar la información, comunicarse con el usuario, el adaptador y el resto de gadgets. La clase commit sólo sirve para almacenar el listado de commits que devuelve el adptador, estando más claro su almacenaje fuera de la clase principal. Muchos de los métodos de la clase git_repository son utilizados para mostrar el interfaz de usuario. Estos métodos los veremos al final de la implementación, explicando su funcionalidad, pero apartándolos de la explicación lógica interna del gadget.
151
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Git_repository +lock +form_config +n_commits +github_radio +changed_repo +repository +user +url +is_configured +lista_commits +github +branches +active_branch +page +alternatives +pagant_enabled +pagsig_enabled +first_load
+select_branch +select_repository +lista_repos +slotRepository +slotSync +eventRepository +eventTree +eventURL +eventSync +eventGithub +saved_repository +saved_url +saved_github +mainAlternative +configAlternative +Alternatives +leftContent +rightContent +hpaned
+init() +createUserInterface() +show_commit(commit) +testFailed() +accept_config1() +displayErrorBranches() +accept_config2() +displayExceptionBranches() +disable_config1() +displayErrorCommits() +disable_config2() +displayExceptionCommits() +disable_config3() +displayErrorRepos() +disable_config4() +displayExceptionRepos() +disable_save() +repaint() +enable_config1() +reload() +enable_config2() +createCell() +enable_config3() +saveForm() +enable_config4() +clearConfig() +enable_save() +save() +createHeaderButton(src, +restore() title, handler) +send_tree(commit) +getTest() +loading(enable) +getRepositories() +setSync(msg) +getBranches() +Send_Syn() +getCommits() +Send_Fin() +testOK(resp) +setRepository(msg) +displayRepos(resp) +goLitePagant() +displayBranches(resp) +goDimPagant() +change_branch(select) +goLitePagsig() +change_repository(select) +goDimPagsig() +displayCommits(resp) +goLiteSave() +prev_commit() +goDimSave() +next_commit() +goLiteClear() +prev_page_github(page) +goDimClear()
commit
+id +tree +author_name +author_email +authored_date +committer_name +committer_email +committed_date +commit_message
1:1
+next_page_github(page)
Figura 3.3.49
152
+add(resp_json)
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.3.2. Métodos por caso de uso 3.3.3.3.2.1. Iniciar_gadget
Método
Nombre
Atributos
MET. 1
Init
eventRepository, eventURL, eventTree, eventGithub, eventSync, saved_repository, saved_url, saved_github, slotSync, slotRepository, mainAlternative, configAlternative
MET. 2
MET. 3
createUserInterface
restore
mainAlternative, configAlternative, is_configured, github, repository, url, form_config, github_radio, alternatives saved_repository, saved_github, github, url, saved_url, is_configured
Parámetros
-
-
-
Tabla 3.3.12 MET. 1 – Init Es el primero que se ejecuta cuando se inicia el gadget. Por ello, su labor es inicializar variables que hagan falta a lo largo de la ejecución. Las variables más importantes que inicializa son las que utiliza la plataforma EzWeb y las necesarias para crear el interfaz de usuario.
eventSync: La variable de sincronización con git-tree, hay que indicarle a EzWeb que la asocie con la descrita en el template (XML) eventTree: Sirve para enviarle a git-tree el hash del árbol que el usuario desea visualizar. eventURL: Sirve para enviarle a git-tree la URL del adaptador, cuando el usuario desea visualizar un árbol.
153
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
eventRepository: Sirve para enviarle a git-tree el nombre del repositorio que le debe indicar al adaptador para obtener el listado de nodos del árbol. En caso de acceso a github, además se incluirá el nombre de usuario de github del dueño del repositorio. eventGithub: Indica a git-tree si el acceso que se está realizando es en local o a github. slotSync: Variable para sincronizarse con github-browser. slotRepository: Mediante esta variable, se recibirá el repositorio seleccionado en github-browser para mostrar en la aplicación saved_repository: Variable para almacenar datos entre sesiones. Hay que asociarla a la variable creada en el template (XML) con este propósito para que EzWeb la reconozca. Almacena el nombre del repositorio a acceder, así como su usuario, en caso de ser necesario. saved_url: Al igual que la anterior, se declara para que EzWeb la reconozca, alberga la URL del adaptador (API). saved_gtihub: Guarda para la próxima sesión el tipo de acceso que se estaba utilizando (local/github).
Además de estas inicializa las variables de la ejecución del gadget. Una vez terminado lanza el método restore para cargar variables de una ejecución anterior. Una vez cargadas, lanza createUserInterface para crear la interfaz de usuario del gadget. Por último, llama a reload para volver a pintar el interfaz y ejecuta getBranches en caso de estar configurado. Si no lo está se queda a la espera de la respuesta del usuario.
MET. 2 – createUserInterface Los detalles de la implementación del interfaz gráfico quedan para una sección posterior. A grandes rasgos, se crea el interfaz de usuario y se almacena en el atributo mainAlternative. Lo importante en este apartado es describir la parte lógica de la solución. En este caso, tras crear el interfaz gráfico, createUserInterface comprueba si el gadget está configurado mediante el atributo 154
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
is_configured. De estar configurado, restore() le habría asignado el valor true. Si está configurado, init llamará a getBranches para desencadenar el mostrado de la información del repositorio. De no estarlo, createUserInterface deja al usuario en la pantalla de configuración, para que introduzca los datos necesarios para la ejecución.
MET. 3 – Restore Es el encargado de cargar los datos de la sesión anterior. Gracias a que init ha inicializado las variables saved_repository, saved_tree y saved_url, el método puede utilizarlas para su propósito. Primero comprueba que estas variables contentan información, si no la contienen, finaliza su ejecución (lo que significará que el gadget no está configurado). Si contienen información, carga todos los datos y rellena los siguientes atributos:
repository: Le asignará el valor de saved_repository. En el caso de acceso a github almacenará el usuario del repositorio y su nombre, con el formato user;repository. Si por el contrario el acceso es local, sencillamente almacenará el nombre del repositorio. Para discernir entre ambos, basta con que compruebe que en la información almacenada está el carácter “;”. url: Le asignará el valor prorpocionado por saved_url. Esta variable almacena la dirección URL del adaptador (API). github: Tendrá como valores true/false, según si el último acceso de la aplicación fue en local o a github. Una vez cargadas las variables finaliza su ejecución.
155
Mario Mira Boronat
3.3.3.3.2.2.
[PROYECTO FINAL DE CARRERA]
Configurar_gadget
Método
Nombre
Atributos
Parámetros
MET. 4
accept_config1
form_config
-
MET. 5
accept_config2
github_radio, form_config
-
MET. 6
getTest
lock
url
MET. 7
getRepositories
-
url
MET. 8
testOK
lock
resp
MET. 9
displayRepos
lista_repos, is_configured, repository, select_repository, form_config
Resp
MET. 10
change_repository
form_config
select
MET. 11
displayErrorRepos
lock
n_error
MET. 12
displayExceptionRepos
lock
n_error
MET. 13
saveForm
github, form_config, repository, url, page, pagant_enabled, pagsig_enabled, is_configured, changed_repo
-
MET. 14
clearConfig
-
-
MET. 15
save
saved_repository, saved_url, saved_github
-
MET. 16
TestFailed
lock
-
Tabla 3.3.13 MET. 4 – accept_config1 La pantalla de configuración se divide en 4 sectores en los que el usuario debe introducir información.
156
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Este método se ejecutará cuando el usuario rellene el primer sector de información y pulse en “Aceptar”. Su cometido es probar que la URL del adaptador que ha introducido el usuario es válida. Para ello, llama al método getTest con la URL introducida. En caso en el cual el usuario no haya introducido nada en el campo de la URL, mostrará un error notificando de ello.
MET. 5 – accept_config2 Al igual que el anterior, se utiliza para validar la configuración del gadget. En este caso, el método analizara las fases 2, 3 y 4 de la configuración. La fase 2 denota si el usuario desea realizar un acceso local o a github con un radio button. Según su elección, si el acceso va a ser local, se comprobará la configuración de 3 y si el acceso es a github, se comprueba la configuración de 4. Tanto en uno como en el otro, deshabilitará las partes de la configuración que ya no hace falta modificar y actualizará los valores internos del gadget con la información proporcionada (repositorio, usuario, tipo de acceso). Por último, tras comprobar que todo es correcto, habilita el botón de “guardar” la configuración, que será el disparador de la obtención del repositorio.
MET. 6 – getTest Envía un “challenge” a la API para comprobar que la URL que se está utilizando efectivamente contiene una API correcta. Para ello primero bloquea el gadget con la pantalla de “loading” y envía una petición asíncrona mediante AJAX a la API con los parámetros de testeo.
157
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Si la respuesta es correcta, se ejecutará el método TestOK, si por el contrario algo falla, se ejecutará TestFailed
MET. 7 – getRepositories Este método lanza una petición asíncrona a la API para obtener los repositorios almacenados en local en la máquina donde esté albergada la API. Si todo va bien, el listado de repositorios se devolverá la manejador displayRepositories, si algo falla se ejecutará displayErrorRepos/displayExceptionRepos según el caso.
MET. 8 – testOK Es el manejador de la petición realizara por getTest, analiza la respuesta de la URL. Si se ha devuelto la cadena para identificar a la API como válida, entonces activa la siguiente fase de la configuración (2). Si la respuesta no ha sido correcta, muestra un mensaje al usuario avisándole de ello.
MET. 9 – displayRepos Es el manejador del evento lanzado por getRepositories, se encarga de mostrar la información recibida en la configuración. En su caso, recibirá un listado con los repositorios almacenados en local en la máquina de la API. Mostrará dicho listado dentro de un desplegable en la fase 3 de la configuración, para que el usuario elija cual quiere visualizar.
MET. 10 – change_repository Cuando el usuario cambia de repositorio en el desplegable rellenado por el método anterior (displayRepos), se lanza este evento que actualiza internamente cuál se ha seleccionado. 158
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 11 – displayErrorRepos Maneja la respuesta de getRepositories, en caso de que haya habido fallo. Muestra el error por pantalla y detiene la ejecución.
MET. 12 – displayExceptionRepos Maneja la respuesta de getRepositories, en caso de que se haya producido algún tipo de excepción. La muestra por pantalla y detiene la ejecución.
MET. 13 – saveForm Es el método que se ejecuta cuando el usuario guarda la configuración del gadget. Guarda todos los datos introducidos por el usuario en los atributos del gadget y llama al método getBranches para que obtenga las ramas del repositorio y se muestre en el interfaz de usuario.
MET. 14 – clearConfig Se ejecuta cuando se pulsa el botón “Clear” en la configuración. Su cometido es reiniciar toda la configuración para introducirla desde el principio.
MET. 15 – save A diferencia de saveForm, que guarda la configuración del gadget en las variables internas del mismo, save guarda la información de configuración dentro de EzWeb, para poder utilizarla en posteriores ejecuciones del programa (cargadas con el método restore).
159
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
MET. 16 – TestFailed Es el manejador de error y de excepción de la llamada a la API del método getTest. Se encarga de avisar al usuario de que la URL de la API introducida o bien no es correcta o hay algún tipo de problema en la conexión.
3.3.3.3.2.3. Mostrar_repositorio
Método
Nombre
Atributos
Parámetros
MET. 17
getBranches
lock, github
url, repository
MET. 18
getCommits
lock, github
url, repository, page
MET. 19
displayBranches
branches, active_branch, first_load, select_branch
resp
MET. 20
displayCommits
n_commits, github, pagant_enabled, pagsig_enabled, lista_commits, lock
resp
MET. 21
displayErrorBranches
lock
n_error
MET. 22
displayExceptionBranches
lock
n_error
MET. 23
displayErrorCommits
lock
n_error
MET. 24
displayExceptionCommits
lock
n_error
MET. 25
Send_tree
eventRepository, eventURL, eventTree
commit
MET. 26
loading
lock
enable
MET. 27
setRepository
form_config
Tabla 3.3.14 160
msg
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
MET. 17 – getBranches Este método bloquea a git-tree mediante el método send_syn(), bloquea al gadget git-commits y realiza la llamada a la API para obtener las ramas (branches) del repositorio actual. Según si el acceso es local o github, utiliza unos parámetros u otros para la llamada. En cualquier caso, inicializa los manejadores de recepción, error y excepción (los cuales son, respectivamente, displayBranches, displayErrorBranches, displayExceptionBranches). MET. 18 – getCommits Tiene el mismo funcionamiento que getBranches, solo que los parámetros que utiliza para llamar a la API, sirven para obtener la información del listado de commits de un repositorio y rama dados. Realiza las mismas tareas de sincronismo e inicializa los manejadores de recepción, error y excepción (los cuales son, respectivamente, displayCommits, displayErrorCommits, displayExceptionCommits).i MET. 19 – displayBranches Es el manejador de la respuesta de getBranches. Recibe como argumento la respuesta en formato JSON de la API. En ella vienen contenidas las ramas de un repositorio dado. Muestra esta información en el interfaz de usuario y prepara la llamada a getCommits con la rama marcada como “active_branch” o rama por defecto. Desbloquea el interfaz de usuario y envía la señal de desbloqueo a git-tree. MET. 20 – displayCommits Es el manejador de la llamada de getCommits. En su argumento, recibe la respuesta en formato JSON de la API, que contiene el listado de commits de un repositorio y rama dados.
161
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
En el caso de ser un acceso local, recibirá 5 commits, ya sean los primeros o intermedios (más sobre esto, más adelante, ya que dependerá de la paginación). En el caso de ser un acceso a github, recibe 30 commits, ya que las limitaciones de dicha web, no permiten obtener más commits. En cualquier caso, muestra 5 por pantalla en el interfaz de usuario, la diferencia estará, en que en accesos locales se paginarán de 5 en 5 commits del primero al último, mientras que en accesos a github, se mostrarán de 5 en 5 hasta 30 commits, pero sin necesidad de hacer una petición a la API para cada página. Desbloquea el interfaz de usuario y envía la señal de desbloqueo a git-tree. MET. 21 – displayErrorBranches Se disparará si ha habido algún error al hacer la petición a la API de las branches. Desbloqueará el interfaz de usuario, enviará la señal de desbloqueo a git-tree y mostrará el error por pantalla. MET. 22 – displayExceptionBranches Se disparará si ha habido alguna excepción al hacer la petición a la API de las branches. Desbloqueará el interfaz de usuario, enviará la señal de desbloqueo a git-tree y mostrará el error por pantalla. MET. 23 – displayErrorCommits Igual que los anteriores, pero para el caso de la petición de commits. MET. 24 – displayExceptionCommits Igual que los anteriores, pero para el caso de la petición de commits. MET. 25 – Send_tree Envía el árbol asociado a un commit al gadget git-tree. Esto ocurrirá cuando el usuario pulse sobre un commit del listado para verlo.
162
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
Junto al árbol, se enviará la información del repositori y la URL de la API. MET. 26 – loading Es el método utilizado para bloquear el gadget. Muestra una capa en pantalla que impide al usuario introducir futuros comandos hasta que se elimine. Los bloqueos/desbloqueos realizados con este método tienen prioridad sobre los que vienen de otros gadgets (git-tree, githubbrowser). De esta forma, si el gadget se bloquea a sí mismo y viene una señal de desbloqueo externa, no se le hará caso, ya que solo puede desbloquearse él mismo. MET. 27 – setRepository Es el método que se ejecuta cuando se recibe un repositorio a visualizar del gadget github-browser. Prepara la información para visualizarlo y lo muestra en el interfaz de usuario.
3.3.3.3.2.4. Cambiar_rama
Método
Nombre
Atributos
MET. 28
change_branch
active_branch, page, pagant_enabled, pagsig_enabled, lock
Parámetros select
Tabla 3.3.15 MET. 28 – change_branch Este método se lanzará cuando el usuario, una vez esté visualizando un repositorio con varias ramas, seleccione otra distinta al actual des delplegable de ramas.
163
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Esto hará que el método change_branch, bloquee al gadget y llame a getCommits con el nuevo parámetro de rama a visualizar. Adicionalmente, almacenará en la información internta del gadget la nueva rama seleccionada.
3.3.3.3.2.5. Seleccionar_commit
Método
Nombre
Atributos
MET. 29
show_commit
lista_commits, hpaned
Parámetros commit
Tabla 3.3.16 MET. 29 – show_commit Es el método que se encarga de mostrar un commit al usuario. Cuando un repositorio sea cargado, o se cambie de rama, se mostrará siempre el primer commit de la lista. Por otra parte, el usuario en cualquier momento puede seleccionar uno de la lista para visualizarlo. El método presentará toda la información del commit, que estará almacenada en la clase commit, con su índice correspondiente, en el interfaz de usuario. Por último, llamará a send_tree, con la información del commit que se necesita enviar a git-tree para visualizar su árbol asociado.
164
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.3.2.6. Cambiar_página
Método
Nombre
Atributos
Parámetros
MET. 30
prev_commit
pagsig_enabled, page, pagant_enabled, github,
-
MET. 31
next_commit
page, pagant_enabled, github, pagsig_enabled
-
MET. 32
prev_page_github
n_commits, pagsig_enabled
page
MET. 33
next_page_github
N_commits, pagsig_enabled
page
Tabla 3.3.17 MET. 30 – prev_commit Este método muestra la página anterior del repositorio en el caso de accesos locales. Para ello, será necesario hacer una nueva petición a la API, para que nos devuelva los 5 commits anteriores al actual. MET. 31 – next_commit Funciona de la misma forma que el anterior, solo que muestra los 5 siguientes commits en vez de los 5 anteriores. MET. 32 – prev_page_github El caso de github tiene un tratamiento distinto al local. Esto es porque de github directamente se devuelven todo los commits a mostrar (el listado completo). Por tanto, no será necesario hacer una nueva petición a la API porque los tenemos almacenados mememoria. Directamente se muestran al usuario. MET. 33 – next_page_github Es el mismo caso que el anterior, pero para siguiente página en vez de página anterior.
165
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.3.3.2.7. Sincronizar
Método
Nombre
Atributos
Parámetros
MET. 34
setSync
-
MET. 35
Send_syn
eventSync
-
MET. 36
Send_Fin
eventSync
url
msg
Tabla 3.3.18 MET. 34 – setSync Se utiliza para sincronizarse con github-browser. Recibirá como argumento el mensaje enviado por dicho gadget, que podrá ser “syn” o “fin”. En el primer caso, bloqueará al gadget y en el último, lo desbloqueará. De esta forma se consigue el sincronimo con github-browser.
MET. 35 – Send_syn Este método envía el mensaje de “Syn” a git-tree para que se bloquee.
MET. 36 – Send_fin Este método envía el mensaje de “Fin” a git-tree para que se desbloquee.
166
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.3.2.8. Modificar_Tamaño
Método
Nombre
Atributos
MET. 37
repaint
alternatives, hpaned
Parámetros -
Tabla 3.3.19 MET. 37 – Restore Cada vez que el usuario modifique el tamaño del gadget o la aplicación necesite refrescarse por algún motivo, EzWeb enviará los nuevos datos de dimensión del gadget al programa y este volverá a dibujar el interfaz de usuario.
3.3.3.3.3.
Template
Se describe en este apartado, las partes importantes del fichero XML (template) del gadget. Ellas son, las que configuran variables con EzWeb para luego poder utilizarlas en su implementación.
De todo el template lo más importante son las variables de Wiring, que nos permiten comunicarnos con otros gadgets. En este caso, se necesita comunicar con los gadgets git-tree y github-browser.
Con git-tree se realizan tareas de sincronismo para bloquearlo/desbloquearlo en las peticiones a la API. Además se le envía la información del árbol a mostrar.
Con github-browser se realizan tareas de sincronismo pasivas (es decir, él será a quien nos bloquee/desbloquee) y además nos envía el nombre de usuario y repositorio de github del repositorio que el usuario ha seleccionado. 167
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
En el siguiente esquema vemos el wiring de forma gráfica:
slotTree
eventTree
slotRepository
eventRepository
slotURL
eventURL
eventSync
slotSync
Git-tree
slotSync
eventSync
Git-commits
Github-browser
slotRepository
eventRepository
Figura 3.3.50
La interacción entre git-tree y git-commits ya fue explicada en el punto 3.3.3.2.3.
La novedad en este caso es git-commits/github-browser, que se comunican mendiante:
eventRepository/slotRepository: transporta el nombre del repositorio a acceder. El acceso siempre será a github con el formato “usuario;nombre”. eventSync/slotSync: Cuando github-browser realice alguna petición a github para obtener el listado de usuarios/repositorios que solicite el usuario, utilizará este canal de información para bloquear a git-commits.
168
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.3.3.1. Propiedades Propiedades
<Platform.StateProperties> <Property name=”saved_repository” type=”text” label=”saved_repository” description=”Last used repository”/> <Property name=”saved_url” type=”text” label=”saved_url” description=”Repository’s API URL”/> <Property name=”saved_github” type=”boolean” label=”saved_github” description=”Acces to github or local”/> </Platform.StateProperties> Git-commits.xml
Se han resaltado en negrita los tags del fichero. Se procede ahora describir los campos:
Platform.StateProperties: Se pueden instanciar tantas como se quiera, en este caso se usan tres: o Saved_github: Almacenará el tipo de acceso a realizar, local o github. o Saved_repository: Según si estamos visualizando repositorios en local o en GitHub se almacenará una información u otra. En el caso local, se guarda el nombre del repositorio visualizado para futuras sesiones. En el caso del acceso a GitHub, se guarda tanto el nombre del repositorio como el nombre de usuario de github asociado al mismo. o Saved_url: Se guarda en este campo la URL de la API a la que se tienen que lanzar las peticiones para obtener los datos de los ficheros a visualizar.
169
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
3.3.3.3.3.2. Wiring Wiring
<Platform.Wiring> <Slot name=”slotSync” type=”text” label=”sync” friendcode=”sync”/> <Slot name=”slotRepository” type=”text” label=”repository” friendcode=”repository”/> <Event name=”eventRepository” type=”text” label=”repository” friendcode=”repository”/> <Event name=”eventUrl” type=”text” label=”url” friendcode=”url”/> <Event name=”eventTree” type=”text” label=”tree” friendcode=”sha1tree”/> <Event name=”eventSync” type=”text” label=”sync” friendcode=”sync”/> </Platform.Wiring> Git-commits.xml
170
En el caso de este gadget, estas variables ya han sido sobradamente detalladas en puntos anteriores.
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.3.3.3.3.
Contexto Contexto
<Platform.Context> <Context name=”user” type=”text” concept=”user_name”/> <GadgetContext name=”height” type=”text” concept=”heightInPixels”/> <GadgetContext name=”lockStatus” type=”text” concept=”lockStatus”/> </Platform.Context> Git-tree.xml
Platform.Context: o User: Nombre de usuario que esta utilizando la plataforma EzWeb. o Height: Altura del gadget. Para redimensionar el interfaz gráfico. o LockStatus: Indica el estado de bloqueo del gadget. Lo utiliza la librería extendida de EzWeb.
3.3.3.3.4.
Interfaz de usuario
Por último, se describe en este apartado el aspecto resultante del gadget, así como los métodos involucrados en la modificación del mismo. Git-commits posee dos interfaces distintos. configuración y otro para mostrar los repositorios.
Uno
para
la
Mostramos en primer lugar el intefaz de configuración en la siguiente figura:
171
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Figura 3.3.51 A esta parte del interfaz la hemos denotado como “A”. A.1.- Es la caja en la que se introduce la URL de la API a acceder, junto con el botón de aceptar. A.2.- En esta caja, seleccionamos el tipo de acceso: local/github. A.3.- Si el acceso es local, se mostrará en esta parte el listado de repositorios del que se dispone. A.4,- Si el acceso es a github, se habilita esta parte para introducir el nombre de usuario y el nombre del repositorio. Adicionalmente vemos en la parte inferior los botones “Save Config” para guardar la configuración y “Clear Data” para iniciar el proceso desde el principio. En la parte superior se encuentran los botones para cambiar entre A y B (Configuración o visualización del repositorio) y un breve texto con el nombre del repositorio actual.
172
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
La parte que muestra el repositorio es la siguiente:
Figura 3.3.52 La denotamos como B: B.5.- Caja que muesta el repositorio actual al lado de los botones para cambiar entre la configuración y esta vista (A y B). B.6.- Selector de Rama. Con este desplegable es con el que se cambia entre las ramas de un repositorio. B.7.- Lista de commits, aquí el usuario puede seleccionar el commit que quiera ver. B.8.- Botones de paginación, para mostrar commits siguientes o anteriores. B.9.- Información del commit, se muesta toda la información posible, datos del autor, del commiter, descripción y los identificadores del árbol y del propio commit.
Las pantallas de carga y error son iguales que en los anteriores gadgets.
173
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Los métodos que afectan al interfaz de usuario son:
Método
Nombre
Descripción
MET. 1
init
Inicializa todas las variables que formarán parte del interfaz.
MET. 2
createUserInterface
Crea todas las capas y elementos del interfaz principal, tanto para A como para B,
MET. 3
ConfigWait
Muestra el mensaje de bloqueo
MET. 4
disable_config1
Deshabilita A.1 cuando es necesario.
MET. 5
disable_config2
Deshabilita A.2 cuando es necesario.
MET. 6
disable_config3
Deshabilita A.3 cuando es necesario.
MET. 7
disable_config4
Deshabilita A.4 cuando es necesario.
MET. 8
disable_save
Deshabilita el botón de “Save Config” en A
MET. 9
enable_config1
Habilita A.1
MET. 10
enable_config2
Habilita A.2
MET. 11
enable_config3
Habilita A.3
MET. 12
enable_config4
Habilita A.4
MET. 13
enable_save
Habilita el botón de “Save Config” en A
MET. 5
displayError
Muestra los mensajes de error.
MET. 10
displayException
Muestra los mensajes de excepción
MET. 16
Loading
Muestra el mensaje de bloqueo
MET. 21
Repaint
Redimensiona el interfaz de usuario según los nuevos valores
Tabla 3.3.20
174
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
3.3.4. Github-browser El úlitmo gadget del conjunto de la solución es un caso especial, ya que no sirve para solucionar el problema planteado, sino para mejorar la interacción con el usuario. Es por ello que no se considera necesario mostrar el diseño de alto y bajo nivel del mismo, directamente se mostrará su interfaz de usuario y sus usos.
3.3.4.1.
Interfaz de usuario
Github-browser es un gadget sencillo, cuyo cometido es buscar repositorios en github. Tiene dos tipos de búsqueda, por nombre de usuario y por nombre de repositorio. En la figura 3.3.53 vemos en la parte de arriba estos dos modos, anotados como A y B. El modo en uso aparece de color rojo. El usuario introduce en la caja de texto la cadena que desea buscar en github. Este gadget, a diferencia del resto, no utiliza el acceso a la API, directamente lanza la petición a Github (que tiene su propia API para manejar este tipo de situaciones) y devuelve la lista proporcionada mostrándola por pantalla. Cuando el usuario desea visualizar un repositorio en concreto, debe pulsar sobre “View Repo”. Esta acción desencadena el envío de los datos de este repositorio a git-commits, como si el usuario hubiera introducido su información en la ventana de configuración.
175
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
De esta forma se puede buscar informaci贸n que al usuario le interese con este gadget y luego visualizarla con el desarrollo del proyecto.
Figura 3.3.53
176
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
4. Conclusiones Llega un momento en la carrera de todo ingeniero, en el que se terminan las asignaturas y se le presenta la tarea de la realización del proyecto final de la misma. En un principio, hay que superar la frustración que genera asimilar, que aunque se haya superado la carrera con éxito, hay mucho conocimiento en el ámbito de la informática del que apenas se conoce su existencia para el recién pseudo-licenciado. Esto se acentúa en el trabajo final de carrera, ya que está muy en contacto con el estado del arte, y dado que la tecnología avanza a pasos agigantados, el futuro ingeniero debe actualizar su conocimiento según el campo que vaya a tratar. En el caso que nos ocupa, el proyecto tiene que ver con el mundo de las nuevas tecnologías Web, área que es abordada en la universidad por el laboratiorio CoNWeT Lab, una disciplina informática que hoy en día se ha convertido en el principal estándar de la presentación de la información en el océano informativo que nos ha brindado internet. Y es que, de eso se ocupan las nuevas tecnologías web, de presentar la información de una manera más atractiva y fácil para el usuario. La información, siempre ha estado ahí, en bibliotecas, en las mentes de los académicos y en las mentes de la gente de a pié, pero gracias a la revolución de la información (que hemos tenido la suerte de presenciar), esta información queda al alcance de cualquiera con las suficientes ganas de acceder a ella. Es por ello que con esta reciente revolución, se ha puesto cada vez más difícil acceder a información útil, ya que esta joven forma de acceder a la información, internet, ha sido inundada por todo tipo de contenido, desde el más académico e interesante, hasta el más mundano e inservible de todos.
177
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Con esta reciente avalancha de contenido, la ciencia se ha preocupado de proporcionar las herramientas necesarias, para que cualquier individuo interesado, sea capaz de enfocar sus atenciones a la información que le interesa. Acaba de nacer la Web 2.0, una web semántica, plagada de servicios que van más allá de mera información, con contenido audiovisual y con un sinfín de datos que en una vida no da tiempo a digerir, y va en aumento. Para visualizar toda esta avalancha de textos, vídeos, audios… se utilizan los navegadores que todos conocemos. Curiosamente, éstos, han pasado a ser la herramienta fundamental de uso diario de millones de personas para acceder a la información. Por ello, la comunidad ha investigado formas mejores de utilizar estos navegadores para acceder al contenido. Una de estas formas, son las plataformas de Mashup y una de estas plataformas de Mashup, es la plataforma EzWeb. El tiempo dirá si esta forma de presentar la información será la que predomine en la guerra de la información, aunque es evidente que la idea es correcta, ya que los últimos dispositivos móviles (teléfonos inteligentes) utilizan esta idea para dar funcionalidades al usuario. Pero no sólo hemos avanzado con internet hacia un mundo en el que la información es accesible por todo el mundo, también hemos avanzado a un mundo en el que la comunicación entre personas para alcanzar una meta, es más fácil que nunca. El ejemplo que nos ha ocupado en el campo de la comunicación, son los repositorios, y dentro de este mundillo, concretamente el sistema de repositorio git. GitHub es una red social de programadores que usan git, ni más ni menos. Permite encontrar a colaboradores que estén programando cosas similares para echar una mano, o ver cómo están enfocando otros compañeros el código de un determinado programa, entre otras cosas. Me ha resultado muy interesante poder trabajar mezclando tantos tipos de conceptos, al fin y al cabo se han desarrollado una serie de gadgets para la plataforma de Mashup EzWeb, que nos sirven para 178
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
presentar de una forma atractiva la información que contiene un repositorio git, ya sea un repositorio instalado en una máquina local, o uno que se encuentre en el citado servicio web GitHub. Para ello, nos apoyaremos en el framework Django, que va a ser el encargado de pedir la información al repositorio git local o al remoto (GitHub) y a entregársela a los gadgets de EzWeb. Lástima que a día de la escritura de estás líneas, nace el nuevo estándar de Internet, HTML5, que en cuestión de un año o dos, predominará en este tipo de sistemas.
179
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
5. Líneas futuras El proyecto realizado se podría ampliar de varias formas.
Por un lado se puede afrontar el hecho de poder modificar los ficheros de los repositorios y enviarlos a las máquinas locales o a github. Es lo que se denomina “hacer un commit”. El problema reside, en que al hacer un commit se deben de resolver una serie de situaciones manualmente, para que las versiones del repositorio mantengan la coherencia. Para implementar estos casos, sería necesario otro gadget, que recibiese los conflictos en forma de cola, para que el usuario fuera solventándolos de uno en uno.
Otra forma de mejorar la solución, sería convertir todo el código al nuevo estándar de presentación web, HTML5 y dentro de muy poco a Javascript2.
Por último también se plantea mejorar la API que accede a los repositorios, para que muestre aun más información
180
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
6. Glosario de términos Plataforma Una plataforma en informática, es un conjunto de software y hardware (aunque no son necesarios ambos) que permite la ejecución de otro software, como puede ser por ejemplo un sistema operativo.
Framework La palabra inglesa framework define, en términos generales, un conjunto estandarizado de conceptos, prácticas y criterios para enfocar un tipo de problemática particular, que sirve como referencia para enfrentar y resolver nuevos problemas de índole similar. En el desarrollo de software, un framework es una estructura conceptual y tecnológica de soporte definida, normalmente con artefactos o módulos de software concretos, con base en la cual otro proyecto de software puede ser organizado y desarrollado. Típicamente, puede incluir soporte de programas, bibliotecas y un lenguaje interpretado entre otros programas para ayudar a desarrollar y unir los diferentes componentes de un proyecto.
Servicio Web Los servicios Web (Web services) son colecciones de protocolos y estándares que sirven para intercambiar datos entre aplicaciones. Distintas aplicaciones software desarrolladas en lenguajes de programación diferentes, y ejecutadas sobre cualquier plataforma, pueden utilizar los servicios Web para intercambiar datos en una red de ordenadores.
181
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
Aplicación Web En la ingeniería de software se denomina aplicación web a aquellas aplicaciones que los usuarios pueden utilizar accediendo a un servidor web a través de Internet o de una intranet mediante un navegador. En otras palabras, es una aplicación software que se codifica en un lenguaje soportado por los navegadores web (HTML, JavaScript, Java, asp.net,php, etc.) en la que se confía la ejecución al navegador. Las aplicaciones web son populares debido a lo práctico del navegador web como cliente ligero, así como a la facilidad para actualizar y mantener aplicaciones web sin distribuir e instalar software a miles de usuarios potenciales. Existen aplicaciones como los webmails, wikis, weblogs, tiendas en línea y la propia Wikipedia que son ejemplos bien conocidos de aplicaciones web. Es importante mencionar que una página Web puede contener elementos que permiten una comunicación activa entre el usuario y la información. Esto permite que el usuario acceda a los datos de modo interactivo, gracias a que la página responderá a cada una de sus acciones, como por ejemplo rellenar y enviar formularios, participar en juegos diversos y acceder a gestores de base de datos de todo tipo
Arquitectura cliente-servidor Esta arquitectura consiste básicamente en un cliente que realiza peticiones a otro programa (el servidor) que le da respuesta. En el ámbito web que nos ocupa, el servidor es la máquina (o máquinas) en internet (o en una red de ordenadores), que nos proporciona el servicio web (o aplicación web) que deseamos utilizar. Mientras que el rol de cliente lo cumple el navegador. De esta forma, es importante entender qué partes se están ejecutando en servidor y qué partes en cliente.
182
[PROYECTO FINAL DE CARRERA] Mario Mira Boronat
API Una API (Aplication programming interface, interfaz de programación de aplicaciones), es un interfaz implementado por un programa software para interactuar con otro software. La idea de una API es una capa de abstracción software, para facilitar el acceso a datos o a funcionalidades de otro programa. En el caso que nos atañe, vamos a tratar con dos APIs, una es la que tenemos que implementar para enviar los datos que solicitan los datos y la otra es la propia API del servicio web GitHub, que nos proporciona los datos de los repositorios git albergados en sus sistemas. Las API‟s independientemente del lenguaje en que implementadas se ejecutan siempre en el lado del servidor.
estén
183
Mario Mira Boronat
[PROYECTO FINAL DE CARRERA]
7. Bibliografía [int05] – Introducción a la ingeniería del software, modelos de desarrollo de programas – 2005 – Fernando Alonso, Loïc Martínez, Fco. Javier Segovia. [net10] - NetVibes, Mayo 2010. URL http://www.netvibes.com. [igo10] iGoogle, septiembre 2009. URL http://www.google.es/ig. [Cro06] D. Crockford. RFC 4627. The application/json Media Type for JavaScript Object Notation (JSON). [BPSM+ 00] T. Bray, J. Paoli, C.M. Sperberg-McQueen, E. Maler, y F. Yergeau. Extensible Markup Language (XML) 1.0. W3C Recommendation, 6, 2000.
184