reingeniería de la aplicación de realización de prácticas ... · en el presente proyecto se ha...

109
Diego Díez Ricondo Reingeniería de la aplicación de realización de prácticas de Bases de Datos Francisco José García Izquierdo y Arturo Jaime Elizondo Facultad de Ciencias, Estudios Agroalimentarios e Informática Grado en Ingeniería Informática 2012-2013 Título Autor/es Director/es Facultad Titulación Departamento TRABAJO FIN DE GRADO Curso Académico

Upload: others

Post on 26-Mar-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Diego Díez Ricondo

Reingeniería de la aplicación de realización de prácticasde Bases de Datos

Francisco José García Izquierdo y Arturo Jaime Elizondo

Facultad de Ciencias, Estudios Agroalimentarios e Informática

Grado en Ingeniería Informática

2012-2013

Título

Autor/es

Director/es

Facultad

Titulación

Departamento

TRABAJO FIN DE GRADO

Curso Académico

© El autor© Universidad de La Rioja, Servicio de Publicaciones, 2013

publicaciones.unirioja.esE-mail: [email protected]

Reingeniería de la aplicación de realización de prácticas de Bases de Datos,trabajo fin de grado

de Diego Díez Ricondo, dirigido por Francisco José García Izquierdo y Arturo Jaime Elizondo (publicado por la Universidad de La Rioja), se difunde bajo una Licencia

Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported. Permisos que vayan más allá de lo cubierto por esta licencia pueden solicitarse a los

titulares del copyright.

Facultad de Ciencias, Estudios Agroalimentarios e Informática

TRABAJO FIN DE GRADO

Grado en Ingeniería Informática

Alumno: Diego Díez Ricondo

Director: Francisco José García Izquierdo

Co-director: Arturo Jaime Elizondo

Logroño, Junio 2013

Reingeniería de la aplicación

de realización de prácticas

de Bases de Datos

2

Índice

Resumen ............................................................................................................................. 3

Abstract ............................................................................................................................... 4

1 Objetivos y Planificación ........................................................................................... 5

1.1 Contextualización ........................................................................................................ 5

1.2 Definición del problema ............................................................................................. 5

1.3 Alcance ........................................................................................................................... 6

1.4 Estimación de tiempos y planificación .................................................................... 8

2 Análisis ......................................................................................................................... 12

2.1 Mejoras a realizar en la aplicación actual ............................................................. 12

2.2 Estudio de las opciones disponibles para el módulo de ayudas ...................... 18

2.3 Parser SQL como proyecto independiente .......................................................... 21

2.4 Justificaciones tecnológicas ................................................................................... 21

3 Diseño .......................................................................................................................... 24

3.1 Compatibilidad entre versiones .............................................................................. 24

3.2 Diseño del módulo de generación de ayudas ..................................................... 24

3.3 Rediseño y reestructuración de clases .................................................................. 27

3.4 Rediseño del sistema de usuarios .......................................................................... 31

3.5 Rediseño del sistema de realizaciones de prácticas .......................................... 31

3.6 Rediseño de la interfaz de usuario ......................................................................... 33

4 Construcción ............................................................................................................. 36

4.1 Implementación del parser ...................................................................................... 36

4.2 Módulo de generación de ayudas al alumno ....................................................... 37

4.3 Nuevo sistema de realización de prácticas .......................................................... 41

4.4 Nuevo sistema de sesiones de usuario................................................................. 44

4.5 Re-implementación del comparador de resultados .......................................... 45

4.6 Nueva interfaz de usuario ........................................................................................ 47

5 Gestión del proyecto ................................................................................................ 50

5.1 Desviación entre estimaciones y tiempo real de desarrollo .............................50

6 Conclusiones.............................................................................................................. 51

7 Referencias ................................................................................................................. 52

3

Resumen

En este proyecto partimos de una aplicación existente cuyo objetivo es la organización, realización y corrección de sesiones de prácticas con el lenguaje SQL de bases de datos relacionales. La desarrollé el año 2010 en el contexto de mi proyecto de ITIG “Plataforma online para realización de prácticas de bases de datos”. Ésta permite a los profesores introducir ejercicios de SQL con soluciones, clasificarlos según dificultad y sesión práctica para la que están planteados. Cada ejercicio puede asignarse a una práctica o liberarlo para practicar fuera del horario lectivo. El alumno introduce para cada ejercicio su solución y la herramienta le muestra el resultado obtenido, el esperado y si coinciden o no. Esta solución recibió el premio a la innovación docente concedido por el Consejo Social de la Universidad de La Rioja en 2012.

La experimentación con la herramienta durante dos cursos académicos ha permitido identificar algunas líneas de mejora. La más ambiciosa era dotar a la aplicación de la capacidad de detectar errores de concepto comunes como el acceso a tablas innecesarias o soluciones poco eficientes como algunas que usan innecesariamente subconsultas. El objetivo es llamar la atención a los alumnos sobre este tipo de cuestiones, transparentes al sistema gestor de bases de datos, y mejorar el aprendizaje.

En el presente proyecto se ha desarrollado la segunda versión de la herramienta. La característica más sobresaliente es que ahora es capaz de detectar un conjunto de errores e ineficiencias, proporcionando a la aplicación cierta inteligencia. Éstos se muestran en forma de mensajes de advertencia. En la versión anterior los mensajes mostrados procedían del gestor de bases de datos. Sin embargo los mensajes actuales son el resultado de un análisis sintáctico de la consulta SQL y de su comparación con la aportada a la herramienta por el profesor. Para llevar a cabo esto último se ha usado como base una herramienta de análisis del lenguaje SQL, que ha resultado ser muy potente tras ser adaptada y extendida para cubrir las necesidades del proyecto.

Además de lo anterior, se ha rediseñado por completo la arquitectura interna de la aplicación, permitiendo añadir algunas funcionalidades muy potentes y mejorando el rendimiento general de la aplicación de manera muy notable. El nuevo sistema de recuperación y entrega automática de prácticas, y la totalmente renovada interfaz de usuario son algunas de las novedades más destacadas.

Palabras clave: Aplicación web, prácticas, bases de datos, SQL, análisis, parser, ayuda, entregas automáticas, Java, Struts2, Spring, Hibernate, Bootstrap, Trabajo Fin de Grado.

4

Abstract

In this project we start from an existing application whose objective is the organization, accomplishment and correction of practical sessions with the SQL relational database language. I developed it in 2010 in the context of my ITIG project "Online platform for performing database practical sessions". It allows teachers to introduce SQL exercises with solutions, classify them according to difficulty and to the corresponding practical session for which they are set out. Each exercise can be assigned to a practical session or released to practice outside class time. The student enters a solution for each exercise and the tool shows its result, the expected one and whether they match or not. The solution was awarded with the teaching innovation prize by the Board of the Universidad de La Rioja in 2012.

After two years’ experience with this tool some areas for improvement have been identified. The most ambitious improvement was to provide it with the ability to detect common misconceptions such as access to unnecessary tables or inefficient solutions such as those ones that unnecessarily use subqueries. The aim is to draw the student’s attention to such issues, which are transparent to the database management system, enhancing the learning process.

The second version of the tool has been developed in this project. The most outstanding feature is that now it is able to detect a number of errors and inefficiencies, simulating intelligence. These are displayed as warning messages. In the previous version the displayed messages came from the database management system. However current messages are the result of parsing the SQL query and compare it against the query provided by the teacher. To carry out the above, we have come out with a SQL language analysis tool, which has proved to be very powerful after being adapted and expanded to meet the project needs.

In addition to the above, the internal architecture of the application has been completely redesigned, which has enabled to introduce some powerful features and to improve the overall performance of the application in a remarkable way. New systems for practices progress backups, automatic practices delivery, and completely revamped user interface are some of the most prominent changes.

Keywords: Web application, practical sessions, databases, SQL, analysis, parser, help, automatic deliveries, Java, Struts2, Spring, Hibernate, Bootstrap, Final Project.

5

1 Objetivos y Planificación

1.1 Contextualización

En la actualidad, y desde hace 3 años, se está utilizando para la asignatura de Bases de Datos del primer curso del Grado en Ingeniería Informática una aplicación que desarrollé y presenté en el año 2010 como Proyecto Fin de Carrera de Ingeniería Técnica en Informática de Gestión.

Dicha herramienta supuso un cambio en la manera en que los alumnos realizaban las prácticas de dicha asignatura. Ésta proporcionaba a los alumnos una plataforma única, donde poder practicar lo aprendido en clase, para diferentes SGBD, ahorrando al alumno toda configuración previa y permitiéndole centrarse exclusivamente en el aprendizaje del lenguaje SQL.

Mientras, al profesor, le permitía confeccionar prácticas, añadir ejercicios de repaso para los alumnos y obtener informes de entregas de las prácticas realizadas por los alumnos, entre otras funcionalidades.

Después de tres años de uso con éxito de la herramienta, se han ido recogiendo ideas sobre posibles mejoras y nuevas funcionalidades que podría tener la aplicación. Una de las mejoras que más interesaban era la posibilidad de que la aplicación no se limitase a determinar si un ejercicio entregado por un alumno era coincidente o erróneo, sino que además la propia herramienta fuese capaz de sugerir al alumno como mejorar su respuesta o ayudarle a conseguir una respuesta correcta.

De esta manera, la aplicación se convertiría en una especie de tutor inteligente, capaz de detectar las deficiencias más comunes en el aprendizaje y corregir al alumno en el mismo instante de realización de los ejercicios.

El objeto de este Trabajo Fin de Grado será añadir las mejoras recogidas durante estos años, teniendo como núcleo principal el dotar de inteligencia a la aplicación para que sea capaz de interpretar las respuestas de los alumnos y corregir o sugerir de qué forma podrían mejorarlas, convirtiéndose de esta manera en un actor principal dentro del proceso de aprendizaje del alumno.

1.2 Definición del problema

La aplicación a mejorar permite, de manera sencilla, resolver ejercicios planteados por el profesor para el aprendizaje del lenguaje de consultas en bases de datos relacionales. Pero, como he comentado anteriormente, uno de los puntos a mejorar que se han observado durante su uso activo en la asignatura de “Bases de Datos” es que, pese a facilitar la ejecución y comprobación de las consultas realizadas por los alumnos, la herramienta no les sugiere cómo deberían mejorar sus consultas para llegar a la respuesta correcta.

Por la naturaleza del lenguaje de consultas SQL, un mismo resultado puede ser obtenido de muchas maneras distintas. El problema radica en decidir de manera automatizada cuándo

6

una solución es correcta o no, ya que dos consultas diferentes pueden devolver los mismos resultados y no por ello tienen porque ser correctas.

Partiendo de la base de que el profesor redacta los ejercicios proporcionando la consulta SQL que resuelve el enunciado correctamente, la dificultad está en determinar si una solución propuesta por el alumno es equivalente. Con equivalentes me refiero a consultas diseñadas para obtener la misma información de una base de datos.

La nueva aplicación ayudará al alumno a conseguir una solución lo más parecida posible a la propuesta por el profesor.

El objetivo final es mejorar el proceso de aprendizaje del alumno, mostrando al alumno sugerencias sobre fallos o errores de concepto típicos durante el aprendizaje del lenguaje SQL. Estas sugerencias, al ser mostradas al alumno en el mismo instante de realización del ejercicio, ayudarán a que el alumno entienda más fácilmente el motivo de los errores cometidos, facilitando una mejor asimilación de conceptos al ser casos totalmente prácticos.

Además de la funcionalidad de generación de ayudas al alumno, también se plantean otros desarrollos para mejorar y extender la aplicación actual:

Mejorar el rendimiento general de la aplicación, reduciendo los recursos necesarios y disminuyendo los tiempos de carga.

Añadir un sistema de log de uso y de incidencias o errores en la aplicación.

Proporcionar nuevas herramientas de gestión, mejorando las ya existentes.

Permitir a un profesor monitorizar los usuarios conectados en la aplicación.

Actualizar la interfaz de usuario, mejorando aspectos de interacción y usabilidad.

Implementar mecanismos que garanticen la conservación del progreso de prácticas de un alumno en caso de reinicio de su equipo o caída del servidor de la aplicación.

Crear un sistema de entrega automática de prácticas de alumnos al finalizar el periodo de realización de éstas.

1.3 Alcance

1.3.1 Módulo de generación de ayudas al alumno

Es el núcleo central y más importante de la nueva versión de la aplicación. Esta nueva funcionalidad permitirá mostrar mensajes de ayuda durante la realización de ejercicios por los alumnos, en función de las respuestas enviadas.

El nuevo módulo deberá ser capaz de detectar y generar ayudas al alumno al encontrar alguno de los cinco siguientes casos, confeccionados en base a los errores más habituales cometidos por los alumnos en años anteriores:

En ocasiones, el alumno hace uso en las consultas de tablas innecesarias para la correcta solución del ejercicio.

7

El alumno abusa del uso de subconsultas, pudiendo llegar a la solución sin usarlas o usando menor número de ellas.

El alumno usa la cláusula GROUP BY de manera errónea, agrupando por campos que no se encuentran definidos en el SELECT (sin contar los agregados). Este problema se ha detectado mayormente en el SGBD MySQL ya que no lanza ningún error al agrupar de manera errónea.

El alumno hace uso de la sentencia DISTINCT como si fuera una función (con paréntesis) que actúa sobre una columna en vez de a nivel de registro.

En ocasiones puede ocurrir que el alumno pase por alto la necesidad de coincidencia de los nombres de las columnas del resultado obtenido y esperado, y pueda pensar que tienen mal resuelto el ejercicio. El sistema deberá notificar cuando los nombres de las columnas sean diferentes.

1.3.2 Sistema de log de uso, incidencias y errores

Uno de los puntos débiles de la anterior aplicación era la falta de información sobre el uso y los errores generados. La nueva aplicación registrará en ficheros de log, de manera sencilla y configurable, diferentes mensajes de uso y errores de la aplicación.

1.3.3 Mejora de las herramientas de gestión

Para la parte de gestión de la aplicación se deciden realizar las propuestas sugeridas por los profesores que han usado la aplicación durante estos tres años, buscando mejorar la usabilidad y agilizar las tareas de gestión:

Permitir modificar los ejercicios de una práctica en realización, haciendo visibles al instante los cambios para los alumnos que se encuentren realizándola.

Añadir más filtros y opciones a los listados de alumnos, esquemas, ejercicios, prácticas y entregas de alumnos.

1.3.4 Monitorización de usuarios conectados

El profesor podrá monitorizar en todo momento que usuarios se encuentran conectados en la aplicación, saber si están realizando ejercicios de repaso y/o prácticas y cuánto tiempo llevan inactivos.

1.3.5 Nueva interfaz de usuario

La nueva aplicación dispondrá de una interfaz de usuario totalmente renovada que tendrá especialmente en cuenta aspectos de usabilidad y facilidad de navegación por la aplicación.

1.3.6 Conservación de prácticas en curso

Un aspecto importante de la nueva aplicación será la posibilidad de continuar con una realización de prácticas inacabada. Para ello la aplicación mantendrá los progresos de prácticas de todos los alumnos mientras no sean entregados o finalice el tiempo de

8

realización de la práctica. Con esta medida se consigue que un alumno nunca pierda su progreso en la realización de una práctica.

1.3.7 Envío automático de realizaciones de prácticas

Esta nueva funcionalidad garantizará la entrega de prácticas de todos los alumnos, forzando la entrega de aquellos alumnos que aún no lo hayan hecho al finalizar el tiempo de realización, notificándoles que su práctica ha sido enviada automáticamente.

1.4 Estimación de tiempos y planificación

1.4.1 Horario

El horario que destinaré a la realización del Trabajo Fin de Grado es el que muestro en la figura inferior. Debido a que actualmente me encuentro trabajando, el horario es más una declaración de intenciones que un horario inamovible, ya que puede ocurrir que tenga periodos con menor carga laboral donde pueda dedicar más horas diarias al TFG y otros donde no tenga tiempo para dedicarle. Las horas marcadas en azul son las destinadas al TFG:

Lunes Martes Miércoles Jueves Viernes Sábado Domingo

10:00

11:00

12:00

13:00

18:00

19:00

20:00

21:00

22:00

23:00

1.4.2 Estimaciones de fases del desarrollo

Las estimaciones de tiempos realizadas sobre las diferentes fases del desarrollo del proyecto se representan en el siguiente diagrama de Gantt. Estas estimaciones son únicamente orientativas, para tener un punto de referencia durante el desarrollo donde medir si el

9

desarrollo va más avanzado de lo estimado y se puede incrementar el alcance del proyecto o por el contrario los tiempos de desarrollo estimados están siendo excedidos.

10

11

1.4.3 Ciclo de vida

El ciclo de vida a seguir en el desarrollo del proyecto será un ciclo de vida Iterativo incremental, donde para cada iteración se generará un producto terminado y funcional.

Para cada iteración se ha fijado una duración de 2 semanas y antes de comenzar cada una de ellas se determinará el alcance de las funcionalidades que entrarán en dicha iteración, ordenadas en función de la prioridad establecida para cada una de ellas.

El modelo elegido, de manera simplificada, va en la línea de las nuevas metodologías ágiles de desarrollo como puede ser Scrum, donde una de las ventajas que proporcionan es la posibilidad de mostrar al cliente, el estado de la aplicación en un estado estable tras cada iteración. Gracias a esto, la aplicación puede ser extendida introduciendo más funcionalidades por iteración si el desarrollo va avanzado respecto a los tiempos estimados.

En mi caso concreto, usar un ciclo de vida iterativo me permitirá añadir progresivamente más funcionalidades al alcance final del proyecto si el desarrollo va avanzado en tiempos.

12

2 Análisis

2.1 Mejoras a realizar en la aplicación actual

Tras haber recogido los requisitos que deberá satisfacer la nueva versión de la aplicación, el siguiente paso será estudiar con detenimiento los cambios necesarios que habrá que realizar, tanto para integrar el nuevo desarrollo de generación de ayudas al alumno como para mejorar el funcionamiento general de la aplicación y añadir el resto de funcionalidades.

Debido al éxito de la aplicación actual durante sus tres años de vida, la nueva aplicación se ha planteado con unas metas muy ambiciosas, realizando cambios muy profundos respecto a la anterior versión, llegando hasta el punto de mantener únicamente el concepto de la aplicación.

A continuación se analizan por separado y en detalle cada uno de los cambios que se han decidido realizar sobre la aplicación.

2.1.1 Ayuda en la realización de ejercicios del alumno

Partiendo de la base de que el desarrollo pretende extender la funcionalidad de una aplicación que ya se encuentra en uso, el primer aspecto a considerar es cómo se va a integrar la nueva funcionalidad de ayudas al alumno en el sistema. Ésta integración debe mirarse desde dos puntos de vista:

El del rediseño de la interfaz de usuario para encajar los nuevos componentes del desarrollo.

Y el de la distribución e interacción interna de la nueva funcionalidad con la aplicación existente.

Para esta nueva funcionalidad se plantea como solución más adecuada la posibilidad de mostrar a los alumnos unos mensajes de ayuda que aparecerán cuando comprueben el resultado de sus consultas. La aplicación comparará varios factores entre la consulta correcta del profesor y la solución proporcionada por el alumno.

Para ello la manera más natural de plantearlo es definiendo criterios de coincidencia o similitud entre las dos consultas. En función del grado de coincidencia de los diferentes criterios definidos se mostrarán unos mensajes u otros (o no se mostrarán mensajes).

También deberá ser posible definir criterios sobre una consulta que no sean necesariamente comparativos, permitiendo estudiar aspectos de ésta que se consideren erróneos.

Los criterios de coincidencia se confeccionarán en función de los errores más habituales detectados a los alumnos. En base a las soluciones entregadas por los alumnos en años anteriores, se han definido cinco criterios principales que pretenden cubrir los casos de error más habituales.

A continuación se detalla el análisis realizado para cada uno de los criterios definidos en la sección Alcance del proyecto:

13

2.1.1.1 Uso de tablas innecesarias

Este criterio es de carácter comparativo, es decir, para que el sistema sea capaz de generar los mensajes de ayuda, deberá analizar dos consultas y comparar el mismo aspecto extraído de cada una de ellas. En primer lugar, el sistema analizará la solución al ejercicio del profesor en busca de las tablas involucradas en la consulta SQL y posteriormente realizará el mismo procedimiento con la respuesta del alumno.

Una vez que se han localizado los conjuntos de tablas involucradas en ambas consultas, para detectar si el alumno está utilizando alguna innecesaria, el sistema quitará del conjunto de tablas del alumno aquellas que también se encuentren en el conjunto de tablas usadas por el profesor.

Tablas innecesarias

Tablas del profesor Tablas del alumno A B

A \ B = diferencia de conjuntos

Tras esta operación, si el conjunto de tablas del alumno todavía contiene alguna quiere decir que esas tablas son innecesarias para la resolución del ejercicio y por lo tanto el sistema deberá mostrar un mensaje al alumno notificando esta situación.

El mensaje a mostrar al alumno no concretará el nombre de las tablas innecesarias, pese a ser técnicamente posible, ya que se ha creído conveniente utilizar un mensaje más genérico para forzar al alumno a pensar de nuevo sobre su respuesta.

2.1.1.2 Uso innecesario o excesivo de subconsultas

De igual manera que el anterior criterio, éste es también comparativo, por lo que el sistema deberá disponer de dos consultas (solución del profesor y respuesta del alumno) para generar los mensajes de ayuda si fuese necesario.

El sistema analizará la solución del profesor, contando el número de subconsultas encontradas dentro de ésta. Hará lo mismo con la respuesta del alumno.

Una vez que el sistema tenga el número de subconsultas usadas para cada una de las dos consultas analizadas, se generarán los mensajes de ayuda en función de las siguientes dos situaciones:

La solución del profesor no usa subconsultas y la del alumno al menos usa una. El mensaje será “Estás haciendo uso de subconsultas cuando este ejercicio se puede resolver sin usarlas.”

14

La solución del profesor tiene N subconsultas y la del alumno tiene más de N. El mensaje en este caso será “El ejercicio se puede resolver usando menos subconsultas.”

Si no se da ninguna de las dos situaciones el sistema no mostrará ningún mensaje.

2.1.1.3 Uso erróneo de GROUP BY

Al contrario que los dos criterios anteriores, este criterio no es comparativo ya que el sistema es capaz de extraer la información necesaria para generar los mensajes de ayuda de una única consulta.

En primer lugar el sistema comprobará si la consulta está haciendo uso de la cláusula GROUP BY, y de igual manera para todas las subconsultas si las hubiese. Después, para cada una de las consultas (consulta principal y subconsultas) que se hayan encontrado con la cláusula GROUP BY se realizará el siguiente proceso:

1. El sistema analizará la consulta, extrayendo cada una de las columnas usadas en la cláusula SELECT y que no se traten de funciones agregación (COUNT, MAX, …).

2. Posteriormente se extraerán de igual manera las columnas usadas en la cláusula GROUP BY.

3. Una vez extraídos los dos conjuntos de columnas, se comprueba que ambos coincidan y en caso contrario se muestra un mensaje notificando del error al alumno.

2.1.1.4 Uso de DISTINCT con paréntesis

Para el análisis de este criterio no es necesaria la comparación con otra consulta, por lo que es suficiente con la propia consulta a analizar.

El sistema buscará en la consulta el uso de la sentencia DISTINCT continuada de una columna envuelta en paréntesis. Si se encuentra la sentencia usada de esta manera, el sistema mostrará un mensaje de ayuda al alumno haciéndole saber que la sentencia DISTINCT actúa a nivel de registro y no de columna.

Este criterio es un poco diferente a los anteriores ya que realmente intenta hacer saber al alumno que el uso que se le está dando a los paréntesis puede que no sea el que el alumno espera.

Sintácticamente un DISTINCT seguido de una columna con paréntesis no es inválido, pero debido a que el uso de paréntesis normalmente se asocia a funciones, el alumno puede llegar a pensar erróneamente que usado de esta manera el DISTINCT solo actuará sobre la columna que se encuentra entre los paréntesis.

2.1.1.5 Nombres de columnas diferentes

En este caso el criterio para la generación de ayudas se basa en la comparación de los nombres de las columnas del resultado obtenido al ejecutar dos consultas diferentes.

Para detectar este criterio y generar el mensaje de ayuda correspondiente, el sistema seguirá el siguiente proceso:

15

1. La solución del profesor se ejecutará contra el esquema de base de datos correspondiente obteniendo el resultado. Del resultado obtenido se extraerán los nombres de las columnas.

2. La respuesta del alumno se ejecutará de igual manera para obtener el resultado. Si la consulta del alumno no es válida y no se puede obtener un resultado de base de datos, el proceso termina y no se muestra ningún mensaje de ayuda al alumno.

3. El sistema compara los nombres de las columnas de los resultados obtenidos por la solución del profesor y la respuesta del alumno y si alguno de ellos no coincide se muestra el mensaje notificando al alumno acerca del error.

Teniendo claro que la solución radica en evaluar las consultas y realizar comparaciones o análisis en base a unos criterios previamente definidos, el problema se traslada únicamente al planteamiento técnico de la solución.

El flujo de realización de un ejercicio por parte de un alumno pasará a ser:

1. Comprensión del ejercicio 2. Confección de la solución SQL 3. Comprobación del resultado 4. Determinación de si el resultado del alumno es coincidente (que no correcto) con el

resultado de la consulta proporcionada por el profesor. 5. Aplicación de los criterios de comparación para obtener los mensajes de sugerencia

de mejora de la solución del alumno. 6. Presentación de las sugerencias (si las hay) y el resultado de la consulta al alumno.

Las sugerencias de realización al alumno únicamente serán informativas y el alumno podrá ignorarlas y enviar la solución de igual manera que se realizaba anteriormente.

2.1.2 Estandarización de la construcción del proyecto

Para facilitar la posterior construcción del proyecto se ha decidido migrar el proyecto a Maven, un sistema de construcción de proyectos Java muy usado y que de una manera muy sencilla permite construir un proyecto desde sus fuentes para obtener la aplicación compilada. De esta manera el proyecto es fácilmente compilable sin necesidad de un entorno de desarrollo, directamente desde la línea de comandos.

Para sacarle el máximo partido al nuevo sistema de construcción del proyecto se ha decidido definir una serie de perfiles para poder compilar el proyecto, por ejemplo, para desarrollo o para puesta en producción.

2.1.3 Implementación de un sistema de logs

Para implementar el nuevo sistema de log de la aplicación se utilizará un framework de logging para facilitar la detección de errores y el seguimiento de uso de la aplicación. Como framework de logging se ha optado por Log4j por ser una opción conocida, robusta y ampliamente usada.

16

La aplicación registrará mensajes a diferentes niveles de detalle, para poder posteriormente decidir si se desea visualizar mayor o menor información sobre el uso de la aplicación.

Además se decide realizar un desarrollo propio para permitir modificar el nivel de log de la aplicación sin tener que pararla, pudiendo por ejemplo mostrar unos mensajes más detallados en casos de sobrecarga o mal funcionamiento de la aplicación para tratar de determinar las causas.

2.1.4 Re-implementación completa de la lógica de negocio de la aplicación

Uno de los cambios más profundos de la aplicación es la refactorización completa todas las clases involucradas en la lógica de negocio.

En la versión anterior de la aplicación, por falta de tiempo y conocimientos, la lógica de la aplicación se encontraba muy ligada a la vista y a la persistencia lo que dificultaba el posterior mantenimiento debido a la alta cohesión entre clases con responsabilidades muy diferentes.

Para esta nueva versión se ha decidido re-implementar toda la lógica para dividir cada una de las capas de la aplicación según su responsabilidad (vista, lógica de negocio, persistencia) y que se relacionen entre ellas mediante interfaces, pudiendo en desarrollos futuros modificar la implementación de cualquier clase de las diferentes capas sin que las demás se vean afectadas.

Habrá que tener especialmente en cuenta a la hora de implementar el aspecto del rendimiento de la aplicación. En la anterior versión de la aplicación era un aspecto secundario pero en esta ocasión es un aspecto que se deberá tener muy en cuenta, cuidando especialmente la memoria usada y los tiempos de respuesta.

Otro cambio a realizar es la reestructuración de clases en un nuevo árbol de paquetes, mejor organizado para delimitar claramente la separación de responsabilidades entre capas.

2.1.5 Rediseño de la interfaz de usuario

Debido a la nueva funcionalidad de generación de ayudas al alumno era necesario un nuevo diseño de la interfaz de realización de ejercicios por parte de los alumnos, para poder incluir los nuevos elementos en la vista.

No obstante, el rediseño no se ha ceñido únicamente a las vistas estrictamente necesarias para esta nueva funcionalidad sino que todas las pantallas de la aplicación en conjunto han sido rediseñadas.

Se han rehecho desde cero todas las vistas de la aplicación, manteniendo la idea primordial, pero con un diseño que trata de simplificar la interfaz, aprovechar mejor los espacios y mejorar la usabilidad y la experiencia de usuario. También se han actualizado todas las librerías usadas en las vistas o se han sustituido por otras opciones más actuales, como por ejemplo el framework Bootstrap para la maquetación html+css de las pantallas y Codemirror para el editor de las consultas SQL.

17

2.1.6 Mejora de las herramientas de gestión

La gestión de la aplicación por parte del profesor necesitaba algunas mejoras y nuevas opciones que se han echado en falta durante su uso.

Entre las mejoras a realizar destacan:

La posibilidad de editar un ejercicio de prácticas directamente desde la página de confección de prácticas.

Poder filtrar el listado de ejercicios por las prácticas en las que se encuentran contenidos.

Poder añadir, eliminar y reordenar los ejercicios de una práctica en curso, pudiendo los alumnos observar los cambios de la práctica en el mismo momento de la modificación.

Añadir otros filtros y ordenaciones al resto de tablas de gestión de la aplicación.

Para abordar los cambios, al ser muy numerosos y en ocasiones de una complejidad de implementación alta se ha optado por realizar una re-implementación completa de la lógica de negocio y las vistas para poder realizar los nuevos desarrollos con éxito.

2.1.7 Recuperación de realizaciones de prácticas en curso

Uno de los posibles problemas que podía sufrir un alumno en la anterior versión de la aplicación es que se le reiniciase o bloquease el equipo en mitad de una realización de prácticas, perdiendo todas las respuestas guardadas para esa práctica. Para la nueva aplicación se ha pensado un sistema que permita a un alumno recuperar una realización inacabada mientras la duración de la práctica no haya finalizado.

Para ello, el nuevo sistema mantendrá todos los progresos de los alumnos, independientemente de si se encuentran conectados o no en la aplicación.

En caso de caída del servidor central de la aplicación, todas estas realizaciones serán salvadas en un formato persistente para poder recuperarlas en el próximo arranque de la aplicación. También se podrán configurar que de manera periódica, la aplicación realice una copia de seguridad del último estado de realizaciones, por si la caída del servidor no es interceptable, como por ejemplo cuando hay una pérdida de corriente eléctrica.

1.1.1 Entrega automática de prácticas

Una de las mejoras a realizar en la nueva versión de la aplicación es la de implementar un sistema que sea capaz de enviar automáticamente las realizaciones de prácticas de los alumnos que se encuentren en curso en el momento de finalización de la práctica. De esta manera se evita el problema que surgía en la anterior versión para aquellos alumnos que realizaban la práctica pero no la enviaban.

Para ello, el nuevo sistema de realización de prácticas obtendrá todas las realizaciones no enviadas en el momento de finalización y las persistirá en base de datos.

18

2.1.8 Tiempo restante de realización de prácticas

En la versión anterior de la aplicación un profesor podía activar una práctica con una duración determinada, pero una vez activada no se mostraba en ningún punto de la aplicación cuando finaliza la práctica activa, ni el tiempo de realización, ni momento de inicio.

Esta nueva funcionalidad permitirá saber en todo momento el tiempo restante de realización de una práctica activa. Como se ha de tener especialmente en cuenta la necesidad de exactitud en el tiempo restante mostrado, se ha pensado en implementarlo mostrando una cuenta atrás al usuario, actualizada en todo momento.

2.1.9 Mejora en la personalización de ejercicios de repaso

Otra de las mejoras necesarias era la de mejorar las opciones que se muestran a la hora de permitir elegir a un alumno que ejercicios de repaso le gustaría realizar.

Anteriormente se mostraban todos los esquemas existentes aunque estos esquemas no tuviesen ejercicios asociados disponibles para realizar de repaso.

En esta nueva versión se ha mejorado este comportamiento, mostrando únicamente aquellos esquemas que tengan ejercicios para realizar como repaso.

2.1.10 Control de usuarios conectados

Esta funcionalidad es totalmente nueva y permite a un profesor saber que usuarios se encuentran conectados en la aplicación, si se encuentran realizando prácticas y/o repasos y el tiempo que llevan inactivos. Además este sistema garantiza que un usuario solo pueda estar conectado en la aplicación desde un único equipo/navegador en el mismo instante. En caso de conectarse desde otro equipo/navegador, por seguridad, se invalida la sesión previa y se recupera toda la información de posibles repasos y prácticas en curso.

Llegados a este punto, creo que esta última sección la deberías poner mucho antes, antes de ponerte a discutir las opciones para lo del parser. Además, me gusta la organización de bloque que has hecho, pero deberías concretar más qué es lo que has hecho (una lista exhaustiva; quizás luego te mande quitar, pero quiero verla, a ver cómo queda).

2.2 Estudio de las opciones disponibles para el módulo de ayudas

Puesto que el lenguaje de consultas SQL es un lenguaje bastante complejo desde el punto de vista de su evaluación y comprensión de manera automatizada, el mayor esfuerzo recaerá con total seguridad en estudiar y plantear un sistema robusto que sea capaz de evaluar de manera fiable los criterios definidos teniendo como entrada consultas SQL sintácticamente válidas.

Para evaluar las consultas SQL y poder aplicar los criterios definidos, se plantean tres posibilidades, por orden creciente de preferencia.

19

Desarrollar completamente, sin apoyarse en ningún desarrollo externo, la evaluación de los criterios mediante evaluación de cadenas, siendo éstas las consultas SQL del profesor y el alumno.

Apoyarse en una herramienta de reconocimiento e interpretación de lenguajes (parser). Estas herramientas o frameworks permiten, definiendo la gramática de un lenguaje, reconocer si las sentencias o palabras de entrada pertenecen a dicho lenguaje.

Utilizar alguna herramienta de interpretación del lenguaje SQL, que nos facilite reconocer los diferentes elementos que componen una consulta SQL.

Puesto que la decisión de una u otra alternativa condicionará de manera clara el desarrollo del proyecto, he creído conveniente dedicar a esta fase del proyecto un esfuerzo importante de investigación y formación, para poder evaluar minuciosamente cada una de las opciones, sus riesgos y potencial futuro.

A continuación detallo el resultado del estudio de las diferentes opciones anteriormente planteada.

2.2.1 Utilización de un parser genérico

La primera opción que he evaluado es la posibilidad de utilizar una herramienta de reconocimiento e interpretación de lenguajes, buscando que el lenguaje de desarrollo principal de dichas herramientas sea Java. Existen en la actualidad varios frameworks de interpretación de lenguajes como son ANTLR o JavaCC, de uso libre, muy potentes y ampliamente usados en infinidad de productos software, desde entornos de desarrollo, hasta buscadores semánticos. Tras indagar un poco, me he decantado por estudiar más en profundidad la herramienta ANTLR por ser más potente y encontrarse bastante bien documentada.

Usar una herramienta de las anteriormente mencionadas conlleva escribir la gramática del lenguaje a evaluar. Por norma general, escribir una buena gramática de un lenguaje como SQL es una tarea que por la complejidad y el tiempo necesario para realizarlo podría ser planteado como un trabajo fin de grado en sí mismo. Aunque existen algunas gramáticas desarrolladas y de código libre que podrían evitarme partir desde cero, tras evaluarlas he llegado a la conclusión de que son gramáticas bastante pobres, sin cambios desde hace varios años o muy ligadas a la sintaxis particular de un SGBD concreto. Para poder aprovechar alguna de ellas debería invertir un tiempo muy importante del proyecto para adaptarlas a mis necesidades, ya que en la aplicación se deben poder evaluar consultas bastante complejas, de diferentes SGBD, por lo la gramática deberá ser lo suficientemente completa y flexible para recoger peculiaridades de cada uno de los SGBD soportados.

Estas herramientas generan a partir de un texto de entrada, y gracias a una gramática bien definida, un AST (Abstract Syntax Tree) que representa en forma de árbol cada uno de los elementos definidos en el fichero de gramática. Una vez obtenido, dicho árbol de sintaxis deberá ser tratado para poder definir un modelo de clases que permita extraer información de la consulta de manera sencilla.

20

Puesto que el tiempo disponible para la consecución del proyecto es limitado y el riesgo de no obtener un resultado suficientemente bueno es elevado, he optado por descartarla y continuar evaluando el resto de posibilidades.

2.2.2 Utilización de un parser específico SQL

La siguiente opción analizada es la de utilizar algún proyecto de código libre que me proporcione la posibilidad de evaluar las consultas SQL y extraer información de ellas sin tener que confeccionar una gramática desde cero o definir un sistema de clases que me permita extraer información de la consulta.

Como fruto de una profunda búsqueda de proyectos existentes que pudiesen encajar con mis necesidades he encontrado dos que pueden servirme de base.

• JSQLParser (http://jsqlparser.sourceforge.net/) • Akiban SQL Parser (http://akiban.github.com/sql-parser)

Además de los dos anteriores, existe un producto comercial que cubriría mis necesidades (http://www.sqlparser.com/), pero no dispone de una licencia libre por lo que queda descartado.

Tanto JSQLParser como Akiban SQL Parser, son dos proyectos que podría utilizar como punto de partida, ya que cada uno de ellos tiene una gramática basada en JavaCC y un modelo de clases definido para tratar el árbol de sintaxis generado por el parser.

Partiendo de la premisa de que será totalmente necesario en ambos casos completar tanto la gramática como el modelo de clases del parser, he optado por Akiban SQL parser por su mejor organización de clases, legibilidad de su gramática y posible potencial futuro, pese a que en un principio, por las pruebas que he realizado, JSQLParser evalúe con éxito mayor número de consultas y más complejas.

La decisión de extender y desarrollar el proyecto Akiban SQL Parser es una apuesta ambiciosa, ya que no solo me permitirá cubrir con creces los objetivos del presente proyecto, sino que además proporcionará una herramienta muy potente para desarrollos futuros, pudiendo analizar consultas SQL de diferentes SGBD de una manera sencilla, sin necesidad de un aprendizaje previo sobre interpretación de lenguajes, únicamente con conocimientos básicos del lenguaje de programación Java.

2.2.3 Desarrollo propio mediante análisis de cadenas

Esta opción es la más costosa en tiempo de diseño y desarrollo, puesto que se han de cubrir muchas variables por tratarse de un lenguaje bastante complejo. También es la opción menos robusta, ya que con la restricción de tiempo impuesta es imposible cubrir todas las peculiaridades de un lenguaje. Como ventaja tiene que siempre se pueden comparar y evaluar dos cadenas (independientemente del lenguaje), por lo que la libertad es máxima.

Esta opción queda descartada tras las conclusiones sacadas en los estudios de las dos opciones anteriores, ya que las probabilidades de conseguir una herramienta inacabada en el tiempo disponible son bastante superiores en este último caso.

21

2.3 Parser SQL como proyecto independiente

Una vez que se ha tomado la decisión de abordar el problema del estudio de las consultas SQL desde un punto de vista bastante ambicioso realizando un análisis completo del lenguaje, parece bastante razonable que esta parte del desarrollo conforme un único proyecto independiente, que una vez completado sea integrado en la aplicación principal.

Plantear la nueva funcionalidad como un proyecto separado de la aplicación principal proporciona la gran ventaja de permitir a otra persona usarlo de manera independiente, pudiendo aprovechar el gran potencial de dicho desarrollo para nuevos proyectos.

En referencia a esto último, el resultado de las mejoras sobre el proyecto se puede encontrar en mi fork del proyecto original en Github https://github.com/didiez/sql-parser. El código es libre de ser estudiado y extendido. Además las modificaciones realizadas durante este desarrollo pueden ser aprovechables por la rama original del proyecto, por lo que tengo la intención de realizar un pull-request para que dichas mejoras pasen a formar parte del proyecto original.

Al afrontar el nuevo desarrollo como un proyecto independiente, queda claro que junto a la propia implementación del parser, uno de los desarrollos imprescindibles en la aplicación principal será diseñar e implementar el nexo de unión entre ambos.

2.4 Justificaciones tecnológicas

A continuación enumero las tecnologías que se usaron en el proyecto inicial y que continúan siendo usadas, en sus versiones más actuales, para esta nueva versión de la aplicación:

Java: lenguaje de programación principal de la aplicación

MySQL: SGBD para la base de datos central de la aplicación

Struts 2: framework MVC para realizar la aplicación web

Hibernate: framework de persistencia

C3p0: herramienta de pool de conexiones

Tiles: herramienta de composición modular de las vistas

Tomcat: contenedor de aplicaciones

JDBC: para la ejecución de consultas contra los diferentes SGBD posibles

jQuery: framework para realizar la interacción de las vistas y peticiones AJAX

jQGrid: plugin de jQuery para realizar las tablas de gestión de la aplicación

Además de las tecnologías anteriormente enumeradas, para este nuevo proyecto se hará uso de otras herramientas/frameworks que enumeraré a continuación.

22

2.4.1 Maven

Maven es una herramienta de software para la gestión y construcción de proyectos Java que ha permitido estandarizar el proceso de construcción de los dos proyectos (Aplicación web principal y Parser SQL) resultantes de este trabajo fin de grado, facilitando el proceso de pruebas y la actualización de las librerías de los diferentes procesos, debido a sus sistema de plugins y control de dependencias.

http://maven.apache.org/

2.4.2 Spring

Se ha decidido hacer uso de Spring ya que es un framework de inversión de dependencias que permite diseñar software muy flexible y configurable.

En la aplicación se ha usado intensivamente para la interconexión entre las capas de vista, negocio y persistencia, control de la transaccionalidad de los métodos de la lógica de negocio, y para programar de manera asíncrona la finalización de los períodos de prácticas.

http://www.springsource.org/

2.4.3 Akiban SQL Parser

Akiban es una framework de parsing del lenguaje SQL, escrito en Java y basado en el analizador sintáctico JavaCC. Éste se ha utilizado como base para implementar todo el sistema de generación de ayudas al alumno, extendiendo su potencial para cubrir todos los casos necesarios en nuestro proyecto.

http://akiban.github.io/sql-parser/

2.4.4 Log4j

Para implementar el sistema de logging de la aplicación se ha optado por usar el framework Log4j por ser uno de los más usados y haberlo usado con éxito en otros proyectos anteriores. Log4j permite mediante un fichero de configuración establecer diferentes niveles de log en función del nivel de detalle que queramos obtener, especialmente útil para tener logs de desarrollo y logs de entornos de producción.

Además en la aplicación se ha desarrollado un pequeño modulo para poder modificar dichos niveles de log en tiempo real mediante JMX (Java Management Extensions). Ver Anexo III.

http://logging.apache.org/log4j/1.2/

2.4.5 Druid

Para proporcionar una alternativa al pool de conexiones usado en la anterior versión de la aplicación (c3p0) se ha añadido otra herramienta más actual (Druid), pudiendo intercambiar entre las diferentes implementaciones de manera sencilla.

Druid es un pool de conexiones desarrollado en Java relativamente reciente pero con un rendimiento bastante bueno y algunas funcionalidades interesantes que el resto de pools de

23

conexiones no proporcionan, como son la visualización de las consultas SQL ejecutadas, estadísticas de tiempos de respuesta, de consultas cacheadas, etc.

https://github.com/alibaba/druid

2.4.6 Bootstrap

Para realizar el rediseño de la interfaz de usuario he utilizado el framework de maquetación Bootstrap. Éste proporciona una base de HTML y hojas de estilos CSS bastante completas y flexibles que permiten un rápido desarrollo y una visualización homogénea para los navegadores más usados.

http://twitter.github.io/bootstrap/

2.4.7 Codemirror

Para proporcionar un editor para la introducción de consultas SQL con coloreado de sintaxis y otras opciones como indentación y atajos de teclado he usado un plugin de jQuery llamado Codemirror. Este plugin sustituye al plugin editArea usado en la anterior versión de la aplicación. Codemirror mejora notablemente el rendimiento respecto a editArea y el coloreado de la sintaxis SQL es más consistente. Además su uso es mucho más sencillo y proporciona muchas otras funcionalidades que editArea no contempla.

http://codemirror.net/

24

3 Diseño

3.1 Compatibilidad entre versiones

La nueva aplicación será diseñada e implementada de manera que sea totalmente compatible con la información generada por la versión anterior y viceversa. Esto quiere decir, que en mitad de un curso lectivo se podría implantar la nueva versión de la aplicación y la información generada por la anterior sería accesible desde la nueva. De igual manera, todos los cambios realizados desde la nueva aplicación serían igualmente válidos para la anterior versión, si por cualquier motivo se decide volver a la versión previa de la aplicación.

Para conseguir esta compatibilidad total entre versiones se ha mantenido intacto el modelo de tablas del esquema en la base de datos, almacenando la misma información, modificando en la nueva aplicación únicamente el diseño de clases utilizado para representan dicha información en memoria.

3.2 Diseño del módulo de generación de ayudas

3.2.1 Diseño del parser

Gran parte de la funcionalidad de ayuda al alumno sobre sus respuestas se apoya en el desarrollo de la herramienta de parsing de consultas SQL. Sin un desarrollo minucioso y fiable de dicho parser, la funcionalidad no tendría sentido ya que podría entorpecer el aprendizaje de los alumnos generando advertencias erróneas y en consecuencia, posibles contradicciones entre los mensajes de la herramienta y lo aprendido en clase.

Un diseño de clases cuidado es crucial a la hora de poder trabajar e implementar con fiabilidad dicha funcionalidad. Debido a que el desarrollo del parser se apoya en un proyecto de código libre con un modelo de clases ya definido, no será necesario diseñar un modelo de clases desde cero.

El principal motivo de elección del proyecto Akiban SQL Parser fue su simple diseño de clases, perfecto para tomarlo como base y extenderlo para que cumpla todas las necesidades del proyecto. No obstante, pese a tener un diseño de clases bastante claro, al parser le falta mucho para poder ser utilizado en el proyecto, por lo que durante la fase de desarrollo se deberán tomar decisiones de diseño para cubrir todos aquellos casos que el parser no contemple.

El diseño de clases del parser está fuertemente basado en el patrón Visitor para facilitar la navegación y extracción de información de los resultados generados del parsing.

El funcionamiento del parser de manera simplificada sería: el parser recibe una cadena de texto que procesa en base a una gramática definida. Traduce la cadena a un árbol de clases donde cada nodo del árbol implementa la interface Visitable. Cada una de estas clases nodo, por implementar la interfaz Visitable, tiene un método aceptar (accept(Visitor)) que recibe al objeto visitante (Visitor) como argumento. Además el propio método accept() llama a su vez al método accept() de todos sus hijos. El visitante es una interfaz que tiene un

25

método visit(Visitable) que recibe como parámetro el nodo Visitable que está visitando, y cuya función será, en mi caso, ir recabando información sobre dicho nodo para más tarde utilizar dicha información para detectar si se deberá generar o no algún mensaje de ayuda al alumno.

En la figura de la derecha se puede observar la interfaz Visitor que deberán implementar aquellos objetos que quieran navegar por todos los nodos del árbol generado por el parser. Además del método principal visit(Visitable) se puede observar como tiene tres métodos más para modificar el comportamiento de la navegación del objeto Visitor por el conjunto de nodos.

En el siguiente diagrama de clases se muestra un pequeño fragmento de las clases de tipo nodo usadas por el parser para generar el árbol de elementos de una consulta SQL parseada.

Aunque en el diagrama solo se muestra una pequeña parte de los diferentes tipos de nodos y su jerarquía de clases, todos los nodos del parser heredan de la clase QueryTreeNode y en consecuencia, todos implementan la interface Visitable.

En el pequeño fragmento de clases elegido para mostrar la estructura y filosofía del parser se encuentran dos de las nuevas clases desarrolladas para cubrir las necesidades de este

26

trabajo fin de grado que el proyecto original no contemplaba. Estas dos clases son IntersectOrExceptOrMinusNode y FullOuterJoinNode.

Gracias a este diseño de clases es relativamente sencillo hacer implementaciones concretas de objetos Visitor para que puedan navegar todo el árbol generado durante el parsing de la consulta para extraer información.

3.2.2 Integración del parser en la aplicación web

Además del diseño de clases de la herramienta de parsing, la nueva funcionalidad requiere de un diseño de clases para la integración de dicha herramienta en la aplicación web.

El módulo de integración consiste básicamente en dos clases que tienen diferentes roles y una interface para acceder a la información de interés de las consultas SQL:

La interface AspectosConsulta proporcionará la signatura de los métodos necesarios y suficientes para evaluar la necesidad de generar todos los mensajes de ayuda posibles. Esta interfaz permite extraer la siguiente información sobre una consulta SQL parseada y analizada:

El número de subconsultas usadas. Las subconsultas pueden tener cualquier grado de anidamiento.

Las tablas involucradas en la consulta. También se tienen en cuenta las tablas usadas en las subconsultas, si las hubiera.

Si existe coherencia entre las columnas de las tablas usadas en la cláusula GROUP BY y SELECT. Este criterio tiene en cuenta que se cumpla también para todas las subconsultas, si las hubiera.

Si se ha encontrado el uso de la sentencia DISTINCT con paréntesis en la consulta.

Una clase BuscaAspectosConsultaVisitor que implementará las interfaces AspectosConsulta y Visitor, que se encargará de ir recogiendo de los árboles de clases correspondientes la información necesaria sobre las diferentes consultas SQL para después poder determinar si se ha de mostrar o no algún mensaje de ayuda al alumno.

Un objeto de esta clase, al ir recorriendo (visitando) cada nodo del árbol, hará un tratamiento específico dependiendo del tipo de nodo que se encuentre visitando y guardará cierta

27

información en el estado del objeto. Al terminar de navegar por todo el árbol generado por el parser, el objeto de la clase BuscaAspectosConsultaVisitor habrá recogido en sus atributos la información necesaria sobre la consulta SQL para posteriormente poder devolver dicha información a través de los métodos de la interface AspectosConsulta anteriormente mencionados.

La otra clase involucrada en la integración del parser en el sistema de generación de ayudas al alumno es la clase ExtractorAdvertencias. Ésta tiene como principal y único método público el método extraerAdvertencias, que recibe como parámetros de entrada dos cadenas de texto, que serán la consulta SQL solución del profesor y respuesta del alumno. Este método devolverá un listado de advertencias que serán las que finalmente se mostrarán en la vista como mensajes de ayuda al alumno.

Esta clase es la encargada de unir todas las partes involucradas. El proceso será el siguiente:

1. En primer lugar llamará al parser para generar los árboles de nodos visitables de las dos consultas proporcionadas.

2. Después instanciará dos objetos distintos de la clase BuscaAspectosConsultaVisitor para extraer información útil de los arboles generados de las consultas SQL.

3. Y por último se encargará de generar y devolver un conjunto de advertencias comparando la información devuelta por los dos objetos BuscaAspectosConsultaVisitor.

3.3 Rediseño y reestructuración de clases

Una de las consecuencias del profundo rediseño planteado es la decisión de desechar e implementar de cero prácticamente la totalidad de la aplicación, favoreciendo la reutilización de código, la convención sobre la configuración y buscando optimizar en el rendimiento de la aplicación en todos los aspectos posibles, desde el número de accesos a base de datos, hasta el número de objetos creados y mantenidos en memoria.

Debido al conocimiento de la aplicación previa, por tratarse de un proyecto propio realizado como Proyecto Fin de Carrera, la re-implementación de la aplicación se considera una tarea abordable, que además permitirá mejorar algunos puntos y corregir errores que de otra manera no se podrían corregir.

Además de una mejora en rendimiento, con esta re-implementación se pretende conseguir un código más claro, simple y mantenible debido a la mayor experiencia por parte del alumno, tanto en las tecnologías ya usadas en el proyecto anterior como en las incluidas para esta nueva versión de la aplicación.

3.3.1 Rediseño de capas lógicas

Uno de los primeros aspectos a corregir de la aplicación anterior, antes de comenzar con la integración de la nueva funcionalidad, era la falta de separación de las capas de presentación, lógica de negocio y persistencia. Pese a que funcionalmente las diferentes secciones y módulos se encontraban claramente separados, desde un punto de vista lógico, las capas de

28

presentación, lógica de negocio y persistencia se encontraban en muchas ocasiones entrelazadas en una única clase.

Cada uno de las capas se define con interfaces para poder modificar de manera sencilla posteriormente la implementación sin tener que modificar las clases que usen dichas funcionalidades. A continuación muestro un diagrama reducido (sin los métodos concretos de las interfaces hijas) de la capa de persistencia:

La implementación de cada una de las interfaces del diagrama se realizará usando el framework Hibernate, pero gracias a dichas interfaces el resto de la aplicación no tiene referencias a la implementación, por lo que en un futuro se podría reemplazar por completo la capa de persistencia usando otras opciones como son JDBC o MyBatis, por ejemplo.

La capa de lógica de negocio está igualmente planteada. Para cada clase de lógica habrá una interfaz que defina su contrato para evitar crear dependencias entre las implementaciones propias de la vista, lógica y persistencia.

Otra ventaja que tiene trabajar con interfaces es la posibilidad de usar un framework de inyección de dependencias como es Spring. Mediante el uso de Spring, se puede configurar mediante anotaciones Java o ficheros de configuración XML, las relaciones entre las diferentes capas, pudiendo cambiar de implementación de manera muy sencilla y sin tener que modificar las clases ya existentes. Las clases que compondrán las diferentes capas se deberán configurar para que Spring sea el encargado de crear objetos de dichas clases e inyectarlos en el resto de componentes de la aplicación. El concepto de inyección de dependencias (DI) es también conocido como Inversión de control (IOC).

Además, gracias al uso de interfaces podemos sacar el máximo partido a Spring aprovechando funcionalidades avanzadas que proporciona como son la configuración de métodos transaccionales y asíncronos. Spring hace uso del concepto de programación orientada a aspectos (AOP), para mediante las interfaces crear proxies que hagan procesos previos y posteriores a la ejecución de los métodos de la lógica de negocio. De esta manera, podemos anotar un método de la lógica de negocio como @Transactional y Spring se

29

encargará de iniciar una transacción antes de entrar al cuerpo del método y de realizar el commit() o rollback() al salir del método, dependiendo del resultado.

A continuación se muestra la explicación anterior sobre la manera en que Spring trabaja con transacciones, de manera más detallada, en formato de diagrama de secuencia.

Para terminar de entender el diagrama el código del nuevo método de la lógica de negocio que representa el diagrama. En él intervienen varias de las funcionalidades de Spring, entre ellas la transaccionalidad.

// FinalizadorAsincronoPracticasServiceImpl.java @Override @Async public void programarFinalizacionPracticaActiva(PracticaActiva practicaActiva, String token){ try { Thread finalizadorPrevio = hilosFinalizadoresPracticas

.put(practicaActiva.getPractica().getId(), Thread.currentThread()); if(finalizadorPrevio != null){ finalizadorPrevio.interrupt(); }

30

Thread.sleep(practicaActiva.getTiempoRestante() * 1000); PracticaActiva practicaActivaEncontrada = realizacionPracticaService

.obtenerPracticaActiva(practicaActiva.getPractica().getId()); if(practicaActivaEncontrada != null

&& practicaActivaEncontrada.hasToken(token)){ realizacionPracticaService

.finalizarPracticaActivaForzandoEntregas( practicaActiva.getPractica());

hilosFinalizadoresPracticas .remove(practicaActiva.getPractica().getId());

} } catch (InterruptedException e) { logger.info("Se ha interrumpido el finalizador del período de" + "realizacion de la práctica " + practicaActiva.getPractica().getId()); } } // RealizacionPracticaServiceImpl.java @Autowired private PracticaDao practicaDao; @Override @Transactional(rollbackFor = Exception.class) public void finalizarPracticaActivaForzandoEntregas(Practica practica){ // Antes de desactivar la práctica, entrego todas las realizaciones

// de alumnos que no hayan entregado todavía for(Entry<String, RealizacionPractica> entry : realizacionesPracticas.entrySet()){ if(entry.getValue().getIdPractica().equals(practica.getId())){ if(logger.isInfoEnabled()){ logger.info("Forzada la entrega de la práctica id="

+ practica.getId() + " del alumno " + entry.getKey()); } entregarRealizacionPracticaAlumno(alumnoDao.get(entry.getKey())); } } // Desactivo la práctica practica.setVisible(false); practicaDao.merge(practica); practicasActivas.remove(practica.getId()); }

En el fragmento de código anterior se muestran dos métodos de la lógica de negocio para la finalización del periodo de realización de una práctica. El primer método anotado como @Async se ejecuta en segundo plano y en el momento de finalizar la práctica llamará al segundo método para desactivar la realización y forzar todas las entregas de los alumnos. Se puede observar como el segundo método está anotado como @Transactional, lo que hará que todas las operaciones de persistencia se ejecuten en una única transacción.

El objeto practicaDao que corresponde a la capa de persistencia ha sido inyectado por Spring de manera automática gracias a la anotación @Autowired configurada en el atributo definido en la clase, por lo que la creación de la instancia de la implementación concreta practicaDaoImpl se delega en Spring.

Explicar con detalle la manera en que Spring proporciona todas estas posibilidades y cómo se debe estructurar una aplicación para sacarle el máximo partido a un framework tan amplio como es Spring daría para otro Trabajo Fin de Grado por sí sólo, por lo que con quedarse con que Spring es el enlace de todas las capas de la nuevas estructura de la aplicación es suficiente.

31

3.4 Rediseño del sistema de usuarios

Se ha rediseñado por completo el sistema de entrada en la aplicación, de manera que se tiene total control sobre los usuarios que se encuentran conectados. Además se ha tenido muy en cuenta la necesidad de poder conectarse desde otro equipo o tras reiniciar el ordenador sin perder el estado anterior, pudiendo por ejemplo, poder continuar con una realización de prácticas que se encontraba en proceso.

Para ello se ha pensado en registrar un escuchador de sesión (HttpSessionListener) que se ejecuta cuando un usuario entra en la aplicación, registrando su información en una lista de usuarios conectados. De igual manera se intercepta cuando un usuario sale de la aplicación o expira su tiempo de sesión por inactividad para des-registrar dicho usuario de la lista de usuarios conectados.

Con este nuevo diseño, también se garantiza que un usuario tan solo pueda estar conectado desde un único equipo a la vez. Para ello, si un usuario entra desde otra ubicación, la aplicación recupera toda la información previa e invalida la sesión anterior.

3.5 Rediseño del sistema de realizaciones de prácticas

Uno de los cambios más necesarios en la aplicación anterior era el sistema de realización de prácticas por parte de los alumnos.

En la anterior versión, cada alumno tenía sus realizaciones de prácticas en su sesión de usuario, por lo que el control de éstas por parte del profesor no era posible. Además, por cómo se encontraba diseñado el sistema, una vez iniciada una práctica era imposible saber cuánto tiempo restante quedaba para su realización. También existía el riesgo de perder todas las realizaciones de alumnos en curso por un apagado repentino del servidor de la aplicación.

Para mejorar estos y otros aspectos, se ha tenido que rediseñar todo el sistema de entregas y estado de realización de los alumnos, ganando en control, mejorando notablemente el rendimiento de la aplicación y permitiendo entre otras cosas forzar las entregas de los

32

alumnos en el momento de finalización del período de prácticas o garantizar que un usuario no perderá su progreso de prácticas por un reinicio de su equipo o caída del servidor de la aplicación.

En el nuevo diseño, la aplicación mantiene en todo momento en una lista todos los progresos de realización de prácticas de los alumnos. Las clases que almacenan estos progresos se han diseñado de manera que el impacto en memoria sea el menor posible, tratando de mantener únicamente la información imprescindible, optando por datos primitivos siempre que sea posible.

Al diseñar el nuevo sistema de esta manera, otra de las ventajas que proporciona es un total control de las realizaciones, cosa que en la anterior versión de la aplicación no ocurría al almacenar cada alumno su progreso en la sesión propia del usuario.

En el nuevo diseño también se ha pensado la manera en que se almacenan las prácticas activas en la aplicación, para proporcionar opciones muy interesantes como son el poder mostrar en todo momento el tiempo restante de la práctica y la posibilidad de modificar una práctica mientras se encuentra en realización, reflejando directamente los cambios para todos los alumnos. Para conseguir todo esto se ha generado una nueva estructura de clases mucho más liviana en términos de memoria que la anterior, más flexible y con más información relevante sobre las prácticas. En la sección de implementación se entrará en más detalles sobre las clases del nuevo sistema.

Para garantizar que un usuario nunca pierda su progreso de realización de prácticas la aplicación mantendrá en memoria todas las realizaciones de alumnos no entregadas, mientras el periodo de realización no haya finalizado, sin importar si el alumno se encuentra conectado a la aplicación o no. Además en caso de caída, antes de replegar la aplicación por completo, serializará todos los progresos de los alumnos a disco para poder recuperarlos en el próximo arranque. Para ello se registra un listener al contexto web que capturará el evento de destrucción o parada de la aplicación, pudiendo realizar la copia de seguridad en ese mismo instante.

Además, también se proporciona la posibilidad de configurar la aplicación para que de manera periódica se guarde el estado de las realizaciones de prácticas, para evitar perder todos los progresos por no poder guardar el estado antes de la caída del servidor, por ejemplo ante una pérdida de corriente eléctrica. El tiempo que deberá pasar en minutos para

33

realizar una nueva copia de seguridad de las realizaciones se configurará mediante una propiedad en el fichero properties de configuración de la aplicación.

3.6 Rediseño de la interfaz de usuario

Para esta nueva versión de la aplicación se ha rediseñado por completo y desde cero la interfaz de usuario para simplificarla y mantener un diseño sobrio y uniforme en todas las pantallas de la aplicación, cuidando mucho la usabilidad, y aprovechando mejor el espacio visual. Además se ha tenido muy en cuenta el aspecto del rendimiento en las interacciones con el usuario y los tiempos de carga necesarios para mostrar la interfaz.

3.6.1 Disposición general de las páginas

Para aprovechar mejor el espacio disponible se ha optado por rediseñar todas las pantallas minimizando el espacio ocupado por la cabecera y el pie, haciendo que sigan siendo siempre visibles pero cediendo todo el espacio posible al contenido central de cada sección.

3.6.2 Páginas de gestión del profesor

Se ha rediseñado el panel principal, añadiendo una tabla donde poder visualizar los usuarios que se encuentran conectados en la aplicación.

En cada una de las secciones se han mejorado las tablas, incluyendo filtros y ordenación en todas sus columnas, integrando los filtros en la propia tabla para aprovechar mejor el espacio y aumentar los tamaños de las cajas de éstos.

Además se ha cuidado que el aspecto y comportamiento sea homogéneo en todas las tablas de las diferentes secciones, por lo que el profesor podrá interactuar de la misma manera gestionando alumnos que gestionando ejercicios, practicas, profesores o esquemas.

I lustración 1 : Rediseño de las tablas de gest ión y f i l t ros

34

También se ha añadido un menú superior de acceso rápido para poder cambiar entre las diferentes secciones de gestión que tiene disponibles el profesor.

I lustración 2: Rediseño de las barras de navegación

3.6.3 Página de realización de un ejercicio

La modificación de la interfaz de usuario más necesaria para esta nueva versión de la aplicación es la de la página de realización de ejercicios, ya que para esta nueva versión, además de la información que se mostraba anteriormente, será necesario mostrar al alumno unos mensajes de ayuda para la realización del ejercicio.

Para esta nueva versión, se ha intentado diseñar la pantalla para hacer más cómoda la realización de ejercicios al alumno, reestructurando los componentes visibles de la página en función de su importancia. El nuevo diseño permite, en el mismo espacio visible mostrar más información, de manera más clara y menos sobrecargada, además de destacar los mensajes de ayuda al alumno cuando sea necesario.

En la figura que muestro a continuación, se pueden observar como principales cambios cómo la navegación de ejercicios se ha resituado en la parte superior de la pantalla, utilizando un código de colores para marcar el estado de los ejercicios y diferenciando claramente el ejercicio actual. También se ha dado más presencia al esquema y SGBD del ejercicio actual. Además se ha introducido en la interfaz un nuevo elemento propio de esta versión: Los mensajes de ayuda al alumno, situados tras el editor de la respuesta del alumno.

35

I lustración 3: Idea de rediseño de la interfaz de e jercic io

36

4 Construcción

En esta sección se detallarán algunos de los aspectos de implementación de la aplicación que puedan resultar de especial interés.

4.1 Implementación del parser

4.1.1 Metodología de desarrollo

A continuación se detallará el proceso que se ha seguido para implementar y extender la funcionalidad del parser para cumplir con los requerimientos impuestos por la aplicación.

Como punto de partida y para garantizar la calidad del nuevo desarrollo, el primer paso ha sido implementar una extensa batería de tests que deberá pasar con éxito la aplicación finalmente acabada.

Esta metodología de desarrollo se denomina TDD (Test Driven Development) y consiste en definir primero los test que debería pasar la aplicación y después ir implementando la propia aplicación para que pase los tests anteriormente definidos. Esta metodología de desarrollo, además de permitir ir implementando poco a poco todos los requerimientos de la aplicación, garantiza un alto grado de calidad en el producto software.

En mi caso, he implementado un sistema para probar el parser contra una batería de 2000 consultas SQL diferentes. Dichas consultas están compuestas por soluciones del profesor a ejercicios planteados en la aplicación y respuestas reales realizadas por alumnos mediante el uso de la aplicación durante este último curso. Con esta batería de pruebas, y una vez que se hayan realizado todos los desarrollos necesarios en el parser para que todas las pruebas pasen satisfactoriamente, se puede garantizar que el nuevo desarrollo funcionará correctamente para cualquier respuesta dada por un alumno.

@Test public void parsingConsultas() throws Exception { SQLParser parser = new SQLParser(); try { parser.parseStatement(consulta); } catch (StandardException ex) { Pattern regex = Pattern.compile("at line (\\d+)"); Matcher regexMatcher = regex.matcher(ex.getMessage()); String resultString = null; int lineaError = lineaInicio; if (regexMatcher.find()) { lineaError += Integer.parseInt(regexMatcher.group(1)); resultString = regexMatcher.replaceAll("at line " + String.valueOf(lineaError)); } Assert.fail(fichero.getName() + ": Línea " + (lineaError) + " --> " + (resultString != null ? resultString : ex.getMessage())); } }

A grandes rasgos, la clase generadora de los tests busca en un directorio ficheros que contienen consultas SQL y se las proporciona al método que se muestra arriba. El método trata de evaluarlas y si la evaluación genera errores, la prueba se considera fallida y muestra un mensaje detallando en que línea de la consulta ha fallado. Este mensaje incluye el texto “… at line (…”. Este proceso se realiza para cada una de las 2000 consultas.

37

4.1.2 Gramática del parser

El núcleo principal del parser es su fichero de gramática, donde se definen todas las peculiaridades del lenguaje SQL.

JoinNode.JoinType joinType() throws StandardException : { JoinNode.JoinType joinType; } { <INNER> { return JoinNode.JoinType.INNER; } | joinType = outerJoinType() [ <OUTER> ] { return joinType; } }

El fragmento de código anterior, correspondiente al fichero de gramática del parser. Básicamente lo que hace es extraer el tipo de una expresión JOIN, entre INNER u OUTER. La sintaxis para este ejemplo tan reducido es sencilla. El primer bloque entre llaves son declaraciones de variables, en este caso el tipo, y el segundo bloque es el cuerpo de la función propiamente dicho. Lo primero que mirará la función es si el siguiente token obtenido del analizador léxico es INNER y si es así, la función devolverá el tipo JoinType.INNER. Si el siguiente token no es INNER entonces prueba con el siguiente caso posible (las diferentes posibilidades se separan por un pipe ‘|’). Se llama a la función outerJoinType() que comprobará y extraerá el tipo concreto de join (en este caso podrá ser LEFT|RIGHT|FULL) en la variable joinType. El token OUTER al encontrarse entre corchetes quiere decir que es un token opcional. Finalmente el método devuelve el tipo de outer join extraído en la llamada a la función outerJoinType().

Algunos de los cambios y añadidos más notables realizados en el parser son:

• Permitir clausulas ASC y DESC tras las columnas de la cláusula GROUP BY (sintaxis válida en MySQL)

• Añadidas funciones especiales de diferentes SGBD • Soporte para clausulas JOIN sin clausulas ON o USING • Soporte para sintaxis de comentarios de línea SQL con # • Soporte para clausula MINUS (equivalente en Oracle a EXCEPT) • Soporte para clausula LIMIT ALL • Soporte para FULL JOIN y FULL OUTER JOIN • Soporte para expresiones complejas dentro de funciones agregación.

4.2 Módulo de generación de ayudas al alumno

Otra de las piezas clave en la nueva versión de la aplicación es la generación de mensajes de ayuda al alumno en función de la consulta SQL enviada por éste.

Este módulo de la aplicación es el nexo de unión entre la aplicación web y la herramienta de parsing SQL. Éste se encarga de estudiar el árbol generado por la herramienta y generar

38

mensajes en función de unos criterios concretos definidos por el profesor, en base a las carencias en el aprendizaje más habituales detectadas a los alumnos en años anteriores.

Como he comentado en la sección de diseño (Ver 3.2.2), el objeto que irá visitando cada uno de los nodos implementará la interfaz AspectosConsulta, que permitirá posteriormente comparar los aspectos extraídos de las consultas del alumno y profesor, para mostrar los mensajes de ayuda.

public interface AspectosConsulta { /** Devuelve el número de subconsultas de la consulta. */ int getNumeroSubconsultas(); /** Devuelve un listado de las tablas involucradas en la consulta, en minúsculas. */ Set<String> getTablas(); boolean isCoherenteColumnasSelectGroupBy(); boolean isTieneDistinctConParentesis(); }

Este es el método principal del objeto que irá visitando todo el árbol generado por el parser. Por cada nodo del árbol irá buscando los diferentes aspectos y modificando su estado en función de si se cumplen o no ciertas condiciones.

@Override public Visitable visit(Visitable visitable) throws StandardException { QueryTreeNode node = (QueryTreeNode)visitable; //Incremento el contador de subconsultas if(subqueryNodeTypes.contains(node.getNodeType())){ numeroSubconsultas++; } // Agrego las tablas if(node.getNodeType() == NodeTypes.FROM_BASE_TABLE){ tablas.add(((FromBaseTable)node).getOrigTableName()

.getTableName().toLowerCase()); } // Busco para los nodos SELECT si las columnas tienen coherencia

// con las definidas en el GROUP BY buscarCoherenciaColumnasSelectGroupBy(node); // Busco si se está intentando usar la cláusula DISTINCT a nivel de columna

// en vez de a nivel de fila. Ejemplo: SELECT DISTINCT(nombre), apellidos // distinct actúa sobre nombre y apellidos, pero al alumno puede pensar que // solo sobre nombre, al haberlo envuelto en paréntesis

buscarDistinctConParentesis(node); return visitable; }

En el código anterior se muestra la implementación concreta de BuscaAspectosConsultaVisitor para el método definido por la interfaz Visitor (Ver 3.2.2) y se puede observar como incrementa el contador de subconsultas si el nodo que está visitando es de tipo subconsulta. También almacena los nombres de las tablas cada vez que visita un nodo de tipo tabla de una cláusula FROM o JOIN. Además se puede observar como también busca aspectos más complejos como son la coherencia entre las clausulas SELECT y GROUP BY y si se está intentando usar la cláusula DISTINCT como una función (con paréntesis).

A continuación se muestra el código de estos dos últimos aspectos comentados.

private void buscarCoherenciaColumnasSelectGroupBy(QueryTreeNode node){ if(node.getNodeType() == NodeTypes.SELECT_NODE){

39

ResultColumnList resultColumnList = ((SelectNode)node) .getResultColumns();

GroupByList groupByList = ((SelectNode)node).getGroupByList(); // Si tiene clasula GROUP BY if(groupByList != null){ Set<String> columnasGroupBy = new HashSet<String>(); Iterator<GroupByColumn> iteratorGroupByColumns = groupByList

.iterator(); while(iteratorGroupByColumns.hasNext()){ columnasGroupBy

.add(iteratorGroupByColumns.next().getColumnName()); } Iterator<ResultColumn> iteratorSelectColumns = resultColumnList

.iterator(); while(coherenteColumnasSelectGroupBy

&& iteratorSelectColumns.hasNext()){ ResultColumn resultColumn = iteratorSelectColumns.next(); // Si no es una columna agregación if(!(resultColumn.getExpression() instanceof AggregateNode)){ if(resultColumn.getExpression() instanceof ColumnReference){ // Saco el nombre de la columna String columnaSinAgregacion = ((ColumnReference)resultColumn

.getExpression()).getColumnName(); // Si en el SELECT hay una columna sin agregación

// que no está en el GROUP BY quiere decir que se // está usando mal la clausula GROUP BY coherenteColumnasSelectGroupBy =

columnasGroupBy.contains(columnaSinAgregacion); } else if(resultColumn instanceof AllResultColumn){ // Cuando se usa GROUP BY no se puede usar *

// en el SELECT coherenteColumnasSelectGroupBy = false; } } } } } }

El fragmento de código anterior muestra el método que se encarga de buscar incoherencias en una consulta entre las columnas definidas en la cláusula SELECT y la cláusula GROUP BY.

private void buscarDistinctConParentesis(QueryTreeNode node){ if(!tieneDistinctConParentesis

&& node.getNodeType() == NodeTypes.SELECT_NODE){ SelectNode selectNode = ((SelectNode)node); if(selectNode.isDistinct()){ Iterator<ResultColumn> iteratorSelectColumns = selectNode.getResultColumns().iterator(); if(iteratorSelectColumns.hasNext()){ ValueNode primeraColumnaExpression = iteratorSelectColumns.next().getExpression(); int inicioPrimeraColumna = primeraColumnaExpression.getBeginOffset(); int finPrimeraColumna = primeraColumnaExpression.getEndOffset(); if(inicioPrimeraColumna != -1){ // Si la columna tiene el nombre de la tabla,

// empiezo a buscar el parentesis izquierdo desde ahí if(primeraColumnaExpression.getTableName() != null){ inicioPrimeraColumna =

inicioPrimeraColumna - primeraColumnaExpression.getTableName().length() - 1;

40

} // Busco la posicion del primer char anterior a la

// columna que no sea 'whitespace' while(Character.isWhitespace(

sourceQuery.charAt(--inicioPrimeraColumna))){} // Busco la posicion del primer char posterior a la

//columna que no sea 'whitespace' while(Character.isWhitespace(

sourceQuery.charAt(++finPrimeraColumna))){} if('(' == sourceQuery.charAt(inicioPrimeraColumna)

&& ')' == sourceQuery.charAt(finPrimeraColumna)){ tieneDistinctConParentesis = true; } } } } } }

El fragmento de código anterior busca en una consulta si la cláusula DISTINCT se está intentando usar como una función con paréntesis para advertir al alumno de que la cláusula actúa a nivel de fila y no de columna.

Por último, muestro el código del método que facilita y encadena todas las llamadas para, pasándole dos consultas SQL, obtener una lista de advertencias para mostrar al alumno.

public static Set<Advertencia> extraerAdvertencias(String solucionProfesor, String respuestaAlumno){ Set<Advertencia> advertencias = new LinkedHashSet<Advertencia>(); try { SQLParser parserProfesor = new SQLParser(); parserProfesor.getFeatures()

.add(SQLParserFeature.MYSQL_COLUMN_AS_FUNCS); SQLParser parserAlumno = new SQLParser(); parserAlumno.getFeatures()

.add(SQLParserFeature.MYSQL_COLUMN_AS_FUNCS); BuscaAspectosConsultaVisitor solucionProfesorVisitor =

new BuscaAspectosConsultaVisitor(solucionProfesor); BuscaAspectosConsultaVisitor respuestaAlumnoVisitor =

new BuscaAspectosConsultaVisitor(respuestaAlumno); // Parseo la solucion del profesor y le paso su buscador de aspectos parserProfesor.parseStatement(

trimAndRemoveLastSemicolons(solucionProfesor)) .accept(solucionProfesorVisitor);

// Parseo la solucion del profesor y le paso su buscador de aspectos parserAlumno.parseStatement(

trimAndRemoveLastSemicolons(respuestaAlumno)) .accept(respuestaAlumnoVisitor);

// Advertencia de uso de tablas innecesarias if(CollectionUtils.subtract(

respuestaAlumnoVisitor.getTablas(), solucionProfesorVisitor.getTablas()).size() > 0){

advertencias.add(Advertencia.TABLAS_INNECESARIAS); } // Advertencia de subconsultas innecesarias if(solucionProfesorVisitor.getNumeroSubconsultas() == 0

&& respuestaAlumnoVisitor.getNumeroSubconsultas() > 0){ advertencias.add(Advertencia.SUBCONSULTAS_INNECESARIAS); } else if(solucionProfesorVisitor.getNumeroSubconsultas() < respuestaAlumnoVisitor.getNumeroSubconsultas()){ advertencias.add(Advertencia.SUBCONSULTAS_EXCESO); }

41

// Advertencia de incongruencia entre columnas de GROUP BY y SELECT if(!respuestaAlumnoVisitor.isCoherenteColumnasSelectGroupBy()){ advertencias.add(Advertencia.SELECT_GROUPBY_INCORRECTO); } // Advertencia de DISTINCT usado con paréntesis if(respuestaAlumnoVisitor.isTieneDistinctConParentesis()){ advertencias.add(Advertencia.DISTINCT_PARENTESIS); } } catch (Throwable t) { // Capturo Throwable ya que puede generar tanto 'com.akiban.sql.StandardException' como 'com.akiban.sql.parser.TokenMgrError' // Advertencia de error de parseo advertencias.add(Advertencia.ERROR_PARSEO); if(logger.isInfoEnabled()){ logger.info(t);}

else if(logger.isDebugEnabled()){ logger.debug(t, t);} } return advertencias; }

4.3 Nuevo sistema de realización de prácticas

En este nueva versión de la aplicación se ha re-implementado por completo el sistema de realización y entrega de prácticas, con un diseño de clases totalmente renovado para solucionar algunas carencias de la anterior versión y mejorar el rendimiento de la aplicación.

Para el nuevo sistema se han generados cinco clases nuevas, a continuación explicaré brevemente cada una de ellas y su rol en el nuevo diseño.

4.3.1 RealizacionPracticaServiceImpl

Clase principal del nuevo sistema que proporciona toda la lógica de negocio referente a las prácticas en activo, realizaciones y entregas de éstas.

Además de proporcionar todos los métodos de manejo, mantiene el estado de las prácticas activas y de las realizaciones en curso por parte de los alumnos.

Como se ha detallado en la sección de diseño, este nuevo sistema permite de una manera sencilla poder monitorizar en cada momento el estado de las prácticas, garantizar que un alumno no perderá su progreso por un reinicio de su equipo y forzar la entrega de todos los alumnos al finalizar el tiempo de realización de una práctica.

A continuación muestro el código reducido a únicamente la definición de los métodos y los atributos que se encargan de mantener el estado de las prácticas y realizaciones en curso.

// Map con las practicas activas (clave = idPractica) private Map<Integer, PracticaActiva> practicasActivas = new ConcurrentHashMap<Integer, PracticaActiva>(); // Map con las realizaciones de prácticas en curso por parte // de los alumnos (clave = cuasi) private Map<String, RealizacionPractica> realizacionesPracticas = new ConcurrentHashMap<String, RealizacionPractica>(); List<PracticaActiva> obtenerPracticasRealizablesPorAlumno(Alumno alumno) { ... } void finalizarPeriodoRealizacionPractica(Practica practica) { ... } void finalizarPeriodosRealizacionTodasPracticas() { ... } void activarPractica(Integer idPractica, int duracionMinutos) { ... } void finalizarPracticaActivaForzandoEntregas(Practica practica) { ... } void refrescarPracticaActiva(Integer idPractica) { ... }

42

PracticaActiva obtenerPracticaActiva(Integer idPractica) { ... } RealizacionPractica obtenerRealizacionPracticaAlumno(Alumno alumno) { ... } RealizacionPractica iniciarRealizacionPracticaAlumno(Alumno alumno,

Integer idPractica) { ... } RealizacionPractica eliminarRealizacionPracticaAlumno(Alumno alumno) { ... } RealizacionPractica restablecerRealizacionPracticaAlumno(Alumno alumno, RealizacionPractica realizacionPractica) { ... } void entregarRealizacionPracticaAlumno(Alumno alumno) { ... } void salvarRealizacionesPracticas() { ... } void recuperarRealizacionesPracticasSalvadas() { ... }

4.3.2 PracticaActiva

Representa una práctica que se encuentra activada para que cualquier alumno pueda comenzar su realización. Una práctica activa, además de la propia práctica con sus ejercicios correspondientes, posee una fecha/hora de inicio y una duración determinada, tras la cual dejará de encontrarse activa. Además posee un valor aleatorio único que usará internamente la aplicación para permitirá aumentar o disminuir su tiempo de realización mientras ésta se encuentra activa.

public class PracticaActiva implements Serializable { private Practica practica; private String token; private long inicio; private int duracionMinutos; // ... constructor, setters & getters ... /** * Devuelve el tiempo restante de realización de la práctica en SEGUNDOS * @return tiempo restante en segundos */ public long getTiempoRestante(){ return (inicio - new Date().getTime())/1000 + duracionMinutos * 60; } public boolean hasToken(String token){ return token.equals(this.token); } public EjercicioPractica getEjercicioNumero(final int numero){ return (EjercicioPractica) CollectionUtils.find(

practica.getEjercicioPracticas(), new Predicate() {

@Override public boolean evaluate(Object object) { return ((EjercicioPractica)object).getNumero() == numero; } }); } }

4.3.3 RealizacionPractica

Representa una realización de una práctica en proceso por parte de un alumno. Esta clase almacena el id de la práctica a la que pertenece, el momento de inicio de la realización por parte del alumno y los ejercicios guardados por el alumno durante la realización.

Esta nueva clase se ha diseñado de tal manera que aunque el profesor cambie durante la realización de la práctica el orden de los ejercicios de la práctica, los alumnos no obtengan incongruencias en sus resultados guardados.

A continuación muestro la parte más relevante del código de la nueva clase.

43

public class RealizacionPractica implements Serializable { private Integer idPractica; private long fechaHoraInicio; private Map<Integer, RespuestaEjercicio> respuestas =

new HashMap<Integer, RespuestaEjercicio>(); public RealizacionPractica(Integer idPractica) { this.idPractica = idPractica; this.fechaHoraInicio = new Date().getTime(); } // ... getters ... public RespuestaEjercicio guardarRespuesta(

RespuestaEjercicio respuestaEjercicioAlumno){ return respuestas

.put(respuestaEjercicioAlumno.getIdEjercicio(), respuestaEjercicioAlumno);

} }

4.3.4 RespuestaEjercicio

Representa una respuesta de un alumno a un ejercicio. Se usa tanto para ejercicios de prácticas como de repaso. En el sistema es utilizado como almacén del estado de una respuesta guardada o probada por un alumno. En él se almacena el id del ejercicio al que corresponde, la query que envió el alumno, si la respuesta es coincidente con la solución del profesor, las advertencias o ayudas que se han detectado en la consulta guardada y el momento en que se envió.

public class RespuestaEjercicio implements Serializable { private Integer idEjercicio; private String query; private boolean correcta; private Set<Advertencia> advertencias; private Date fechaHora; // ... }

4.3.5 ResultadoRespuestaEjercicio

En el sistema hace las veces de objeto de transporte desde la lógica de negocio a la vista, para mostrar el resultado de la respuesta enviada en forma de tabla con todos los registros obtenidos, las ayudas que se pueden mostrar al alumno sobre su respuesta y si dicha respuesta es coincidente con la propuesta por el profesor para el ejercicio.

public class ResultadoRespuestaEjercicio { private boolean coincidente = true; private String resultado; private Set<Advertencia> advertencias = new HashSet<Advertencia>(); // ... }

Estas cinco clases en conjunto, junto con otras dos clases que se encargan de conectar este sistema con las vistas de ejercicios de prácticas y de repaso, conforman la nueva implementación del sistema de realización de ejercicios de prácticas.

Con este nuevo sistema se han minimizado los accesos a base de datos ya que el estado de la práctica activa se mantiene en memoria durante su período de realización y debido al diseño de clases mucho más simple y liviano se ha conseguido reducir drásticamente el impacto en

44

memoria que suponía la misma funcionalidad en la versión previa de la aplicación. Esto es así porque, en esta nueva versión, una práctica se encuentra instanciada una única vez, en contraposición de la anterior versión donde para cada alumno se creaba una nueva instancia de la práctica con todos sus ejercicios.

4.4 Nuevo sistema de sesiones de usuario

Otro aspecto que la anterior versión de la aplicación necesitaba mejorar era el de la gestión de los usuarios conectados, ya que podía ocurrir que un usuario cerrase el navegador o reiniciase el equipo accidentalmente y perdiese todos los ejercicios que hubiese guardado durante una realización de prácticas.

En esta nueva versión, además de solucionar este problema se ha ido un poco más allá, diseñándolo de tal manera que un profesor pueda saber que usuarios hay conectados en la aplicación en cada momento, cuánto tiempo llevan inactivos y si están realizando una práctica y/o repaso. Además el sistema garantiza que un usuario tan solo puede estar conectado a la aplicación desde un único punto en el mismo momento, por lo que el sistema es mucho más seguro también para el alumno, que sabe que nadie más está accediendo a la aplicación con su cuenta puesto que de ser así se le forzaría la salida de la aplicación.

La nueva implementación, por simplificar, tiene como gran novedad una clase que almacena la lista de usuarios conectados junto a sus sesiones y es la encargada de gestionar la entrada y salida de usuarios de la aplicación. Si un usuario entra en la aplicación desde una nueva sesión (navegador diferente, equipo diferente, etc), esta clase recupera la información previa del alumno, si existe, y la invalida, por lo que el equipo que anteriormente se encontrase conectado no podría continuar en la aplicación sin introducir de nuevo el usuario y contraseña.

Muestro un fragmento reducido de código de la nueva clase

public class UserSessionListener implements HttpSessionListener, HttpSessionAttributeListener { // Map <cuasi, session> public static final Map<String, HttpSession> userSessions =

new HashMap<String, HttpSession>(); // ... @Override public void attributeAdded(HttpSessionBindingEvent event) { // Si establezco el valor usuario en session, añado

// el usuario en el map de usuarios logueados en la aplicación if(event.getName().equals(AppSessionKey.USUARIO.getClave())){ Usuario usuario = (Usuario)event.getValue(); logger.info("El usuario "

+ usuario.getCuasi() + " ha entrado en la aplicación."); // Si hay una session previa, copio toda la información

// contenida en ésta e invalido la antigua HttpSession sessionPrevia = userSessions.get(usuario.getCuasi()); if(sessionPrevia != null){ for(AppSessionKey sessionKey : AppSessionKey.values()){ event.getSession()

.setAttribute(sessionKey.getClave(), sessionPrevia.getAttribute(sessionKey.getClave())); }

45

// Si es alumno y está en el proceso de realización // de una práctica:

// guardo la práctica actual, ya que al invalidar la sesión // la eliminará y deberé volver a añadirla después

RealizacionPractica realizacionPractica = null; if(usuario.getAlumno() != null){ realizacionPractica = getRealizacionPracticaService(event)

.obtenerRealizacionPracticaAlumno(usuario.getAlumno()); } // Invalido la session anterior sessionPrevia.invalidate(); // Añado la práctica en proceso si la hubiera if(realizacionPractica != null){ getRealizacionPracticaService(event)

.restablecerRealizacionPracticaAlumno( usuario.getAlumno(), realizacionPractica);

} logger.info("Se ha destruido una session previa del usuario "

+ usuario.getCuasi() + " al hacer login, incorporando la " + "información previa a la nueva session.");

} // Añado el nuevo usuario logueado y su session al map userSessions.put(usuario.getCuasi(), event.getSession()); } } // ... }

4.5 Re-implementación del comparador de resultados

Otro cambio realizado es la refactorización del comparador de resultados de las consultas SQL, la entregada por el alumno y la propuesta por el profesor.

En la anterior versión se detectó un error en algunos casos concretos con resultados que devolvían columnas con nulos. Se realizó un parche para solucionar el problema, pero aun así el código de comparación era poco eficiente y su modificación era compleja debido a una complejidad innecesaria en el estilo de programación.

Debido a que además, para esta nueva versión se requería añadir un mensaje de ayuda al alumno cuando los nombres de las columnas de los resultados obtenidos diferían, se optó por reimplementar de manera más clara, eficiente y mantenible el mismo comportamiento, corrigiendo algún otro error de la anterior versión detectado durante la reimplementación.

El resultado de la nueva versión del comparador resulta en un método seis veces más corto, reutilizable tanto para ejercicios de prácticas como para ejercicios de repaso, que cubre tanto los ejercicios donde el orden de los registros es importante como los que no, y que además añade mensajes de ayuda cuando los nombres de las columnas del resultado obtenido difieren de las del resultado esperado.

Muestro un fragmento del método, excluyendo algunas líneas para una mejor legibilidad.

public static ResultadoRespuestaEjercicio resolveAnswer( Ejercicio ejercicio, String respuestaAlumno) { // Determino si se deberá tener en cuenta el orden o no boolean ordered = ejercicio.getQuery().toLowerCase().contains("order by"); // variables con, ps, rs ...

46

// Añado las advertencias resultadoRespuesta.addAllAdvertencias(ExtractorAdvertencias .extraerAdvertencias(ejercicio.getQuery(), respuestaAlumno)); try { StringBuilder resultado = new StringBuilder(); con = DBUtil.getConnection(ejercicio.getEsquema()); if (con != null) { con.setReadOnly(true); psAlumno = con.prepareStatement(respuestaAlumno); psEsperado = con.prepareStatement(ejercicio.getQuery()); if (psAlumno.execute() && psEsperado.execute()) { // Resultado esperado resEsperado = psEsperado.getResultSet(); // Número de columnas del resultado esperado int columnasResultadoEsperado = resEsperado.getMetaData() .getColumnCount(); // ArrayList --> Para tener en cuenta el orden de los registros // HashBag --> Para NO tener en cuenta el orden de

// los registros Collection<List<String>> filasResultadoEsperado = ordered

? new ArrayList<List<String>>() : new HashBag(); while (resEsperado.next()) { List<String> fila = new ArrayList<String>(); for (int i = 1; i <= columnasResultadoEsperado; i++) { fila.add(resEsperado.getString(i)); } filasResultadoEsperado.add(fila); } // Resultado del alumno resAlumno = psAlumno.getResultSet(); // Número de columnas del resultado del alumno int columnasResultadoAlumno = resAlumno.getMetaData() .getColumnCount(); // Comprobamos que tengan el mismo número de columnas if (columnasResultadoEsperado != columnasResultadoAlumno) { resultadoRespuesta.setCoincidente(false); } resultado.append("<table><tr>"); // Nombres de las columnas String resMetaString; for (int i = 1; i <= columnasResultadoAlumno; i++) { resMetaString = resAlumno.getMetaData().getColumnLabel( i); // Si queremos que tambien tengan que coincidir los // nombres de las columnas if (resultadoRespuesta.isCoincidente() && !resEsperado.getMetaData().getColumnLabel(i) .equals(resMetaString)) { resultadoRespuesta.setCoincidente(false); resultadoRespuesta .addAdvertencia(

Advertencia.COLUMNAS_NOMBRES_DIFERENTES); } resultado.append("<th>")

.append(resMetaString) .append("</th>"); } resultado.append("</tr>"); // ArrayList --> Para tener en cuenta el orden de los registros // HashBag --> Para NO tener en cuenta el orden de

// los registros Collection<List<String>> filasResultadoAlumno = ordered ? new ArrayList<List<String>>() : new HashBag(); while (resAlumno.next()) {

47

resultado.append("<tr>"); List<String> fila = new ArrayList<String>(); for (int i = 1; i <= columnasResultadoAlumno; i++) { String valor = resAlumno.getString(i); fila.add(valor); resultado.append("<td>").append(valor) .append("</td>"); } resultado.append("</tr>"); filasResultadoAlumno.add(fila); } resultado.append("</table>"); // Comprobamos si el resultado esperado y el obtenido por el // alumno son iguales if (!filasResultadoEsperado.equals(filasResultadoAlumno)) { resultadoRespuesta.setCoincidente(false); } } else { resultadoRespuesta.setCoincidente(false); } } resultadoRespuesta.setResultado(resultado.toString()); } catch (SQLException e) { resultadoRespuesta.setCoincidente(false); resultadoRespuesta.setResultado(e.getMessage()); } finally {

// ... libero recursos ... } return resultadoRespuesta; } }

4.6 Nueva interfaz de usuario

El aspecto visual y de interacción con el usuario ha sido re-implementado desde cero, cuidando la usabilidad, mejorando la interacción, el aspecto visual y renovando completamente la experiencia de usuario. Este cambio es visible en todas las pantallas de la aplicación, tanto para la gestión de la aplicación por los módulos de gestión solo accesibles por profesores, como para las pantallas de realización.

Desde el punto de vista técnico, las páginas de gestión de la aplicación se han implementado de manera muy modular, centralizando la lógica de las tablas en forma de plugins jQuery, con un código mucho más limpio, robusto y mantenible.

Para la maquetación de todas las páginas se ha usado el framework Bootstrap que agiliza el desarrollo proporcionando unos estilos base que dividen la interfaz en 12 columnas. Además, se ha realizado la página de manera ‘responsive’ en dos tamaños, para que se también se visualice bien la aplicación en pantallas con una resolución menor.

Otro aspecto que se ha tenido en cuenta es aligerar la carga de recursos de las páginas Para ello se han comprimido y unificado todos los recursos css y javascript, además de realizar sprites para la carga de los iconos.

A continuación muestro cuatro ejemplos de la nueva interfaz de la aplicación ya implementada:

48

I lustración 4: Tabla de gest ión de e je rcic ios de l panel del profesor

I lustración 5 : Pantal la del a lumno para la real ización de un e jercic io

49

I lustración 6: Panel pr incipal de gest ión del profesor

I lustración 7: Fragmento del panel pr incipal de l a lumno

50

5 Gestión del proyecto

En esta sección comentaré los aspectos relevantes de la gestión del proyecto, así como las desviaciones entre la planificación y los tiempos de desarrollo reales.

5.1 Desviación entre estimaciones y tiempo real de desarrollo

Las estimaciones previas al inicio del proyecto se realizaron teniendo en mente que para el desarrollo de la nueva funcionalidad de ayuda al alumno mediante el análisis de las consultas SQL era difícil estimar el esfuerzo necesario hasta que no encontrarse inmerso en el problema. Por ello las estimaciones de tiempos para el estudio, formación y desarrollo de esta funcionalidad del proyecto se realizaron con margen suficiente para cubrir todos los posibles riesgos.

Durante el transcurso del proyecto se vio que el desarrollo de éste se encontraba bastante avanzado respecto a las estimaciones por lo que se decidió incluir nuevas funcionalidades en el alcance que en un primer momento no se habían introducido.

Debido a este aumento importante en el alcance del proyecto, el tiempo finalmente dedicado al Trabajo Fin de Grado ha sido el estimado en un primer momento, aprovechando el tiempo restante para implementar nuevas funcionalidades y mejoras.

51

6 Conclusiones

La conclusión más importante que obtengo del proyecto es el éxito en la consecución de todos los objetivos planteados para esta nueva versión.

No solo se han realizado las nuevas mejoras y funcionalidades que se plantearon en el momento de elegir continuar con la aplicación, sino que se ha conseguido una aplicación totalmente renovada, con muchas más funcionalidades que se encontraban fuera del alcance inicial y una herramienta de ayuda al alumno y análisis SQL mucho más potente de lo inicialmente esperado.

Por las mejoras en el rendimiento y la gran cantidad de novedades estoy seguro de que esta nueva versión supondrá un gran cambio tanto para los alumnos como para los profesores que la acaben usando en la asignatura de Bases de Datos del Grado en Ingeniería Informática.

Además, este desarrollo deja una buena base para que la aplicación pueda ser extendida en un futuro, por ejemplo por otros alumnos como su Trabajo Fin de Grado. Algunas posibles ideas que se me ocurren para aprovechar el potente desarrollo de análisis de consultas SQL son:

Realizar un desarrollo para dotar a la aplicación la capacidad de evaluar directamente la corrección de los ejercicios enviados por los alumnos, pudiendo determinar cuándo una consulta se considera correcta o no, sin la necesidad de la supervisión de un profesor.

Realizar un módulo de estadística y seguimiento de la manera en que los alumnos aprenden el lenguaje SQL. El nuevo módulo iría recogiendo información sobre las consultas que los alumnos ejecutan hasta llegar a la que finalmente entregan, pudiendo extraer conclusiones de dicha información recogida para mejorar el proceso de aprendizaje de los alumnos. Este desarrollo es especialmente interesante ya que permitiría a un profesor mejorar la manera en que plantea sus clases y el temario a impartir en función de las conclusiones obtenidas por este módulo estadístico.

52

7 Referencias

Spring Framework reference http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/pdf/spring-framework-reference.pdf

Hibernate Core Reference Manual http://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html_single/

Hibernate Developer Guide http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html_single/

JavaCC Tutorial http://www.engr.mun.ca/~theo/JavaCC-Tutorial/javacc-tutorial.pdf

jQGrid Wiki pages http://www.trirand.com/jqgridwiki/doku.php

Bootstrap project page http://twitter.github.io/bootstrap/

Codemirror manual and reference guide http://codemirror.net/doc/manual.html

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

Anexos

Anexo I - Reuniones ......................................................................................................... 1

Anexo II - Manual de construcción y despliegue ...................................................... 8

Elementos necesarios ........................................................................................................ 8

Construcción de la aplicación desde el código fuente .............................................. 8

Creación de la base de datos............................................................................................ 9

Configuración previa del servidor de aplicaciones Tomcat .................................... 11

Configuración de la aplicación ...................................................................................... 12

Despliegue de la aplicación en Tomcat ....................................................................... 14

Configuración de usuarios para los esquemas ........................................................... 14

Anexo III - Monitorización mediante JMX ................................................................ 22

Anexo IV - Manual de usuario del profesor .............................................................. 24

Login .................................................................................................................................... 24

Recuperar contraseña ...................................................................................................... 25

Perfil ..................................................................................................................................... 25

Menú de navegación ........................................................................................................ 26

Panel profesor .................................................................................................................... 27

Gestión de Profesores ...................................................................................................... 27

Gestión de Alumnos ......................................................................................................... 29

Gestión de Esquemas ....................................................................................................... 31

Gestión de Ejercicios ........................................................................................................ 32

Gestión de prácticas ......................................................................................................... 35

Edición detallada de práctica ......................................................................................... 36

Gestión de entregas ......................................................................................................... 38

Cambio de curso .............................................................................................................. 40

Anexo V - Manual de usuario del alumno ................................................................. 41

Login .................................................................................................................................... 41

Habilitar cuenta ................................................................................................................. 41

Recuperar contraseña ...................................................................................................... 42

Perfil ..................................................................................................................................... 43

Menú de navegación ....................................................................................................... 44

Panel alumno .................................................................................................................... 44

Realización de ejercicios de repaso .............................................................................. 45

Realización de práctica ................................................................................................... 49

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

1

Anexo I - Reuniones

El proceso de comunicación entre las partes involucradas en el presente Trabajo Fin de Grado ha sido principalmente vía correo electrónico. No obstante, durante el transcurso del proyecto se han realizado seis reuniones presenciales. A continuación muestro el motivo, participantes y conclusiones de cada una de ellas.

Fecha 22/01/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 19:00

Hora finalización 19:45

Asistentes Francisco José García Izquierdo

Naziha Ayachi

David Porres

Santiago Román Viguera

Francisco Sariego

Diego Díez Ricondo

Orden del día Reunión inicial de organización

Agenda

1. Puesta en conocimiento del director del Trabajo Fin de Grado a todos sus

tutorandos de la planificación de tiempos y reuniones de seguimiento establecidas

para la realización del Trabajo Fin de Grado.

2. Aclaraciones de dudas generales sobre el Trabajo Fin de Grado.

Resultado de la reunión

1. Todos los asistentes de la reunión aceptan la planificación propuesta y se

comprometen a enviar para el día 1 de Febrero un correo electrónico al director

con los objetivos del Trabajo Fin de Grado propio, y para el día 15 de Febrero otro

correo electrónico con el análisis y la planificación.

2. Se acuerda con el director la posibilidad de mantener reuniones presenciales

individuales los Martes a las 19:00 previo aviso por correo electrónico.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

2

Fecha 30/01/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 16:00

Hora finalización 16:40

Asistentes Francisco José García Izquierdo

Arturo Jaime Elizondo

Diego Díez Ricondo

Orden del día Fijar alcance del TFG

Agenda

1. Fijar en común cual será el alcance del Trabajo Fin de Grado y dentro del alcance

establecer prioridades a cada una de las tareas.

Resultado de la reunión

1. Los asistentes a la reunión acuerdan fijar el alcance del proyecto en dos grandes

puntos:

a. Desarrollar un nuevo módulo en la aplicación que sea capaz de mostrar

mensajes de ayuda al alumno durante la realización de ejercicios, basado

en el análisis de las consultas SQL de su respuesta y la solución del

profesor.

b. Mejorar el rendimiento general de la aplicación.

Fuera del alcance se plantean añadir nuevas funcionalidades a la aplicación que

permitan un mayor control sobre ella. Las nuevas funcionalidades planteadas son

muchas y se abordarán en mayor o menor medida dependiendo del tiempo

disponible tras finalizar los desarrollos principales.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

3

Fecha 20/02/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 19:00

Hora finalización 19:30

Asistentes Francisco José García Izquierdo

Diego Díez Ricondo

Orden del día Reunión de seguimiento

Agenda

1. Exponer al director del Trabajo Fin de Grado el estado actual del desarrollo y las

decisiones que se han tomado hasta la fecha.

Se ha iniciado la refactorización del proyecto para agilizar el desarrollo, el proceso

de construcción, pruebas y sistema de log. Además se ha comenzado a investigar

sobre la decisión a tomar respecto a la manera en que se planteará el problema de

la evaluación de las consultas SQL.

Resultado de la reunión

1. El director y el alumno acuerdan volver a quedar transcurrido un mes para

comentar posibles dudas y controlar que el proyecto se encuentra dentro de los

tiempos planificados.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

4

Fecha 20/03/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 13:00

Hora finalización 13:45

Asistentes Francisco José García Izquierdo

Diego Díez Ricondo

Orden del día Reunión de seguimiento

Agenda

1. Comentar el estado actual del proyecto frente a la planificación inicial.

El desarrollo va bastante adelantado respecto a la planificación por lo que el

alcance del proyecto se amplia, introduciendo mejoras que inicialmente se había

descartado debido a la duración del desarrollo.

2. Planteamiento de dudas al director

Se plantean algunas cuestiones de aspectos funcionales de la aplicación.

Resultado de la reunión

1. El director y el alumno quedan en terminar de resolver vía correo electrónico

alguna de las dudas planteadas, para involucrar en las decisiones a los demás

participantes del proyecto que no se encontraban presentes en la reunión.

2. El alumno se compromete a tener una versión de la aplicación funcional para la

próxima reunión presencial dentro de un mes aproximadamente. La aplicación

deberá mostrar al menos parte de la nueva funcionalidad de ayudas a la

realización de ejercicios.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

5

Fecha 24/04/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 18:45

Hora finalización 19:45

Asistentes Francisco José García Izquierdo

Arturo Jaime Elizondo

César Domínguez

Diego Díez Ricondo

Orden del día Presentación de la aplicación en funcionamiento

Agenda

1. Presentar a los participantes del proyecto el desarrollo funcionando.

Se presentan las nueva aplicación, con el diseño de la interfaz de gestión

totalmente renovado, la refactorización e implementación de todas las mejoras

propuestas en el alcance ampliado del proyecto y a falta de finalizar algunas

carencias del parser e implementar algunos criterios de generación de ayudas a los

alumnos.

2. Planteamiento de mejoras o dudas funcionales de la aplicación

Debido a la potencia del desarrollo realizado, se propone ampliar el alcance de los

criterios a estudiar sobre las consultas inicialmente planteadas. También se

escuchan sugerencias sobre algunas nuevas mejoras que no se plantearon

inicialmente pero que debido al estado avanzando del desarrollo se pueden llevar

a cabo. (Ver anexo II)

Resultado de la reunión

1. La nueva aplicación es vista con bueno ojos por todos los asistentes a la reunión.

2. El alumno acuerda con el resto de asistentes a la reunión en finalizar el desarrollo

del sistema de generación de mensajes de ayuda para la próxima reunión fijada el

día 8 de Mayo. Además el alumno se compromete también a realizar las mejoras

propuestas en esta reunión, mostrando la aplicación terminada, totalmente

funcional, incluyendo las nuevas líneas de mejora.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

6

Fecha 08/05/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 19:00

Hora finalización 20:30

Asistentes Francisco José García Izquierdo

Arturo Jaime Elizondo

César Domínguez

Diego Díez Ricondo

Orden del día Presentación de la aplicación final con últimas mejoras

Agenda

1. Presentar a los asistentes la aplicación terminada.

Se presenta el resultado final del proyecto, incluyendo las mejoras propuestas en

la última reunión presencial. Además se muestra en funcionamiento el sistema de

generación de ayudas al alumno, y todas las funcionalidades extra que inicialmente

no se encontraban dentro del alcance del proyecto.

Resultado de la reunión

1. La aplicación cumple sobradamente el objetivo del proyecto y la sensación

unánime es que el alcance y las mejoras realizadas sobre la aplicación superan con

creces las expectativas iniciales, no solo en la nueva funcionalidad sino también en

el resto de aspectos de la aplicación.

2. El alumno acuerda con el director del proyecto en enviar un borrador de la

memoria del proyecto para la tercera semana de Mayo.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

7

Fecha 06/06/2013

Lugar Universidad de la Rioja - Dpto. de Matemáticas y Computación

Hora inicio 19:00

Hora finalización 19:35

Asistentes Francisco José García Izquierdo

Arturo Jaime Elizondo

Diego Díez Ricondo

Orden del día Firma de documentos y última planificación

Agenda

1. Firma de documentos para el depósito del Trabajo Fin de Grado.

2. Planificar el trabajo desde la reunión hasta la fecha de la defensa.

Resultado de la reunión

1. El alumno acuerda con el director y co-director del trabajo en comenzar a preparar

la presentación para la defensa del Trabajo Fin de Grado.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

8

Anexo II - Manual de construcción y despliegue

A continuación vamos a detallar los pasos a seguir para poder desplegar la aplicación en un nuevo servidor.

Elementos necesarios

Para el despliegue de la aplicación necesitaremos tener en el servidor los siguientes elementos:

Compilado de la aplicación web: La aplicación propiamente dicha, empaquetada en un fichero WAR para poder ser desplegada en un servidor de aplicaciones.

Tomcat 6.0+: Para poder desplegar la aplicación deberemos tener este contenedor de Servlets en su versión 6.0 o superior instalado en el servidor.

MySQL Server 5.1+: También necesitaremos tener instalado el SGBD MySQL en su versión 5.1 o superior, para poder crear la base de datos que usará la aplicación para poder funcionar correctamente. Esta base de datos no tiene por qué estar en el mismo servidor, puede estar en otro siempre y cuando se pueda establecer la conexión con dicha base de datos.

Además de estos dos últimos elementos anteriores, que en caso de no tenerlos instalados podremos descargarlos de sus páginas oficiales, es recomendable para seguir las instrucciones de este manual de despliegue, instalar las herramientas de interfaz gráfica de usuario para MySQL. También se podrán encontrar para ser descargadas en la página oficial de MySQL, con el nombre de MySQL GUI Tools.

Como elementos del proyecto, se proporcionan el script de creación para la base de datos, llamado AplicacionBD.sql, y un fichero que contendrá todo el código y que usaremos para desplegar la aplicación en el contenedor Tomcat, llamado AplicacionBD.war.

Construcción de la aplicación desde el código fuente

Pese a que se entrega junto a los fuentes una versión compilada de la aplicación, en algún momento puede requerirse construirla de nuevo. Para esta tarea se hará uso de la herramienta de construcción Maven.

La construcción mediante Maven es muy sencilla, tan solo es necesario tener Maven instalado en el equipo y conexión a internet para que se puedan descargar automática las dependencias del proyecto.

Abriendo una línea de comandos ejecutaremos lo siguiente desde el directorio raíz del proyecto a compilar, al mismo nivel que el fichero pom.xml

mvn install

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

9

La ejecución es idéntica para empaquetar e instalar en el equipo los dos proyectos fruto del presente Trabajo Fin de Grado (parser y aplicación web).

Creación de la base de datos

Para crear la base de datos que usará la aplicación, usaremos la herramienta de MySQL contenida en el paquete MySQL GUI Tools, llamada MySQL Administrator, mediante la cual cargaremos el script de creación de la base de datos.

Los pasos a seguir para cargar el fichero y ejecutarlos son los siguientes:

Lo primero que deberemos hacer al abrir el programa MySQL Query Browser, será conectarnos con nuestra instancia de MySQL. Para ello introduciremos los datos de conexión como se muestra en la siguiente captura:

Una vez rellenados los datos, pulsaremos en el botón OK.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

10

En la pantalla q nos aparece nos situaremos en la opción de la izquierda Restore y pulsaremos el botón Open Backup File para examinar el fichero AplicacionBD.sql.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

11

Una vez que lo hayamos seleccionado pulsaremos el botón Start Restore y tras unos segundos ya tendremos creado nuestro esquema para la aplicación.

Configuración previa del servidor de aplicaciones Tomcat

Para un correcto funcionamiento de la aplicación sobre el servidor de aplicaciones y para habilitar algunas opciones extras de control es necesario modificar la configuración por defecto del servidor, Tomcat en nuestro caso.

Puesto que la aplicación correrá sobre un servidor Windows explicaré los pasos a seguir para este sistema, pero sería extrapolable para un servidor Linux.

Si el servidor de aplicaciones se arranca como un proceso normal, basta con situar un fichero con el nombre setenv.bat en el mismo directorio que startup.bat, <TOMCAT_HOME>/bin/. Ese fichero se lee durante el arranque del Tomcat y establece las opciones a usar. El contenido del fichero es:

Las opciones lo que hacen básicamente es aumentar la memoria disponible para el servidor, tanto la memoria destinada para el HEAP (inicial=256mb, máx=512mb) como para el PERMANENT GENERATION (128mb) donde se cargan las definiciones de las clases.

Además las últimas cuatro línea permiten habilitar JMX en el tomcat para realizar algunas tareas de monitorización y gestión de la aplicación interesantes. JMX es una tecnología estándar de Java que proporciona la posibilidad de monitorizar y gestionar aplicaciones Java.

Si el servidor Tomcat se encuentra como servicio de Windows, las configuraciones anteriores se introducen ejecutando el fichero tomcat6w.exe situado en <TOMCAT_HOME>/bin/ y en la pestaña Java, añadiendo al final de las opciones del textarea ‘Java Options’ las opciones comentadas anteriormente. En las cajas posteriores se introducirán los nuevos valores de memoria para el servidor.

set CATALINA_OPTS= -Xms256m -Xmx512m -XX:MaxPermSize=128m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=localhost

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

12

Los valores de las opciones anteriormente comentadas pueden ser modificados para adecuarse a las características del sistema donde se vaya a desplegar la aplicación.

Además, para su correcto funcionamiento, habrá que configurar el servidor Tomcat para que el encoding usado en las peticiones sea UTF-8.

Para ello habrá que modificar el fichero server.xml situado en <TOMCAT_HOME>/conf/ y editar la línea del conector HTTP para añadir lo siguiente:

Esto último es importante ya que de no ser configurado así, cuando desde las tablas de gestión se realicen filtros con caracteres especiales, las tablas no mostrarán los registros debidamente filtrados.

Configuración de la aplicación

Base de datos y servidor de correo

La aplicación por defecto tiene una configuración de base de datos y de servidor de correo que se deberá modificar para que la aplicación se pueda conectar al esquema propio de la base de datos y el servidor de correo que se vaya a utilizar para enviar correos de habilitación de alumno y recuperación de contraseña.

Todos los parámetros de configuración de la aplicación se encuentran en un único fichero aplicacionbd.properties:

<Connector protocol="HTTP/1.1" ... URIEncoding="UTF-8"/>

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

13

Cada vez que se realice un cambio en este fichero de configuración se deberá reiniciar Tomcat para que se inicie el contexto de la aplicación con los nuevos datos del fichero de configuración.

El parámetro url.application será la ruta para conectarnos a nuestra aplicación desde un navegador, y será usado para confeccionar los links para permitir habilitar las cuentas a los alumnos.

El parámetro app.realizacionesPracticasBackup.cron.expression permitirá mediante una expresión CRON programar copias de seguridad de las realizaciones de prácticas para poder recuperar los progresos de los alumnos en caso de pérdida de corriente eléctrica del servidor de la aplicación.

Ficheros de Internacionalización

La aplicación tiene la posibilidad de mostrarse íntegramente en diferentes idiomas, para ello tan solo habrá que crear un nuevo fichero de configuración para el idioma nuevo a implementar y deberá llamarse siguiente la siguiente regla:

view-messages_<código.idioma>.properties En el caso de no encontrarse un fichero para el idioma, se usará el idioma por defecto, que es inglés en nuestro caso. A continuación muestro una parte del fichero view-messages_es.properties

# URL de la aplicación app.url=http://localhost:8084/aplicacionbd/ # Cron expression para la realización de las copias de seguridad automáticas de las realizaciones de prácticas # Por defecto cada 5 minutos: 0 */5 * * * ? # Más información: http://quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06 app.realizacionesPracticasBackup.cron.expression=0 */5 * * * ? # Flag para no permitir modificar ejercicios que ya hayan sido entregados por algún alumno app.commitedExercises.locked=false # Propiedades de conexión de la base de datos de la aplicación jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/aplicacionbd jdbc.user=root jdbc.password=**** # Propiedades del servidor de correo

password.current=Contraseña actual password.forgot=¿Olvidaste tu contraseña? password.new=Nueva contraseña password.noequals=Las contraseñas introducidas deben coincidir. password.repeat=Repita la contraseña password.required=La contraseña es obligatoria.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

14

Despliegue de la aplicación en Tomcat

Para el despliegue de la aplicación en Tomcat, los pasos a seguir son muy sencillos.

Para desplegarla bastará con copiar el fichero AplicacionBD.war en la carpeta webapps del directorio de Tomcat y si Tomcat está iniciado, él mismo se encargará de desplegar la estructura de directorios y todo lo necesario para el funcionamiento de la aplicación.

Configuración de usuarios para los esquemas

Para evitar que al ejecutar soluciones dadas por los alumnos para los ejercicios, contra sus respectivos esquemas, modifiquen los datos contenidos en éstos, deberemos asegurarnos de que los usuarios que se usan para realizar las conexiones a los distintos esquemas no tienen privilegios de modificación. A continuación vamos a explicar detalladamente los pasos a seguir para configurar correctamente los usuarios en los distintos SGBD posibles.

MySQL

Para configurar los usuarios en MySQL usaremos la misma herramienta que se ha comentado para la creación de la base de datos, el MySQL Administrator. Nos conectaremos a la instancia de MySQL y en las opciones de la izquierda nos situaremos en User Administration.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

15

Rellenaremos el formulario para crear un nuevo usuario, introduciendo el nombre de usuario y la contraseña (dos veces, para evitar errores). Tras haber introducidos esos datos, nos dirigiremos a la pestaña Schema Privileges donde podremos otorgar los privilegios que deseemos sobre los distintos esquemas disponibles.

En nuestro caso como solo queremos permitirle realizar consultas, elegiremos solo el privilegio SELECT, y en nuestro caso lo haremos con los esquemas biblioteca y comercio.

Una vez hayamos elegido los privilegios pulsaremos en Add new user si estamos creando el usuario, o Apply changes si estamos modificando un usuario existente.

Tras esto, ya podremos modificar los datos de conexión para los esquemas de la aplicación de biblioteca y comercio en MySQL, para que se conecten con el nuevo usuario userapbd.

MS SQL Server

De igual manera que hemos hecho para MySQL, deberemos hacerlo para los esquemas a los que nos estemos conectando desde la aplicación, por el mismo motivo, evitar que se modifiquen los datos del esquema.

Lo primero será conectarnos a la instancia de MS SQL Server introduciendo los datos de conexión. En nuestro caso la autentificación se hace mediante la autentificación de Windows.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

16

Una vez conectados, deberemos dirigirnos a la ruta de carpetas que aparece a la izquierda de la pantalla, Instancia > Seguridad > Inicios de sesión.

Para crear un nuevo inicio de sesión pulsaremos con el botón derecho sobre el icono y elegiremos la opción, crear inicio de sesión.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

17

Rellenaremos los campos que nos aparecen y desmarcaremos la opción que dice el usuario debe cambiar la contraseña en el siguiente inicio de sesión. Una vez relleno pulsaremos en Aceptar y ya habremos creado un nuevo inicio de sesión.

Ahora tan solo nos faltará crear el usuario que se conectará con este nuevo inicio de sesión.

Para ello, deberemos dirigirnos a cada una de las bases de datos para las que queremos crear los usuarios y en la sub carpeta Seguridad > Usuarios de cada base de datos deberemos crear un nuevo usuario.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

18

Pulsando con el botón derecho sobre el icono de usuarios podremos crear un nuevo usuario.

En el formulario que nos aparecerá deberemos rellenar el nombre del usuario con el que nos conectaremos, el nombre del inicio de sesión que hemos creado anteriormente y el esquema predeterminado para el usuario.

Además deberemos otorgarle tan solo permisos de lectura, y para ello marcaremos únicamente en los listados inferiores las propiedades db_datareader.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

19

Si no recordamos el nombre del inicio de sesión, podremos examinarlo.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

20

De igual modo que en el caso del inicio de sesión, también podremos examinar el esquema predeterminado para el usuario.

Oracle

Para Oracle, la manera de conseguir lo que deseamos es algo más enrevesada.

Para comenzar a trabajar nos deberemos conectar con un usuario con privilegios para crear usuarios nuevos y definir sinónimos públicos.

Lo primero que haremos será crear un nuevo usuario y darle privilegios de conexión.

Una vez que tenemos creado el nuevo usuario, deberemos crear unos sinónimos para las tablas del esquema al que realizaremos las consultas desde la aplicación. Los sinónimos nos

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

21

servirán para que un usuario cualquiera pueda referirse a una tabla cuyo propietario es un usuario diferente, sin tener que anteponer el nombre de usuario a la tabla.

En nuestro caso, la tabla proveedores fue creada por el usuario Scott, por lo que la definición del sinónimo quedaría de la siguiente manera:

Una vez creado el sinónimo, tan solo nos quedará darle privilegios al nuevo usuario para poder hacer SELECT sobre el nuevo sinónimo definido. Se haría de la siguiente manera:

Este mismo procedimiento se deberá hacer con todas las tablas del esquema.

Este método de creación de sinónimos es el único posible si queremos llamar a las tablas sin el prefijo del propietario, y no tener privilegios de modificación sobre éstas.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

22

Anexo III - Monitorización mediante JMX

Para monitorizar el estado de la aplicación y poder realizar algunas tareas de gestión como modificar los niveles de log de la aplicación usaremos la tecnología estándar de Java, JMX (Java Management Extensions).

Existen multitud de tutoriales y guías en internet sobre cómo sacar el máximo partido a JMX, por lo a modo de ejemplo usaré la herramienta VisualVM para conectarme mediante JMX a la aplicación web y modificar los niveles de log para mostrar información más detallada del uso de la aplicación, para buscar el motivo de un mal comportamiento por ejemplo.

Para este ejemplo me he descargado la aplicación VisualVM y al ejecutarla se observa como en el equipo local detecta que hay un servidor Tomcat arrancado, por lo que lo selecciono para entrar a monitorizarlo.

En caso de querer monitorizar un servidor Tomcat situado en otra máquina, habrá que añadirlo mediante la IP de la máquina y el puerto que se configuro para el JMX del Tomcat (Ver Configuración previa del servidor de aplicaciones Tomcat).

Al seleccionar el servidor, dentro de las pestañas que aparecen nos dirigiremos a MBeans y dentro del árbol que aparece pulsaremos sobre es.didiez.util.log para acceder al módulo que permitirá modificar los niveles de log de la aplicación en vivo.

En la imagen siguiente se muestra como se podría establecer el nivel de log DEBUG para todos los logs propios de la aplicación pulsando el botón assignDebug, en caso de necesidad por estar desarrollando o buscando algún error inesperado.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

23

En la pestaña “Notifications”, si hemos pulsado el botón “Suscribe” podremos ver una lista con todos los cambios de nivel de log realizados, en nuestro caso, el cambio comentado anteriormente.

Este ejemplo es solo uno de los muchos usos que se le puede dar a JMX. En internet hay mucha información sobre los diferentes usos de JMX y las herramientas visuales existentes (VisualVM, JConsole, etc.)

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

24

Anexo IV - Manual de usuario del profesor

Este manual está destinado para aquellos usuarios de la aplicación que sean profesores.

Login

Para poder entrar en el sistema hay que introducir unas credenciales antes, para ello hay que dirigirse a la sección de Login pulsando el botón Entrar situado en la parte superior derecha de la aplicación o desde el formulario que se encuentra en la propia página de inicio de la aplicación.

En el formulario de entrada procederemos a introducir nuestros datos, si se desconocen los datos de conexión en el primer uso de la aplicación, póngase en contacto con el profesor.

Si recordamos nuestros datos, tan solo faltará pulsar el botón Entrar. Si por el contrario hemos olvidado nuestra contraseña, podemos recuperarla desde el enlace ¿Olvidaste tu contraseña? Para recuperar la contraseña ver Recuperar contraseña.

Para entrar por primera vez en la aplicación, deberemos hacerlo con el profesor por defecto de la aplicación, cuyos datos de conexión son:

Usuario: admin Contraseña: 1234

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

25

Recuperar contraseña

Esta función nos permite recuperar la contraseña, en caso de haberla olvidado, para ello deberemos rellenar el formulario con nuestros datos, el nombre de usuario y el email de contacto que introdujimos durante la primera entrada al sistema.

Para llegar a la pantalla de Recuperar contraseña, se hace pulsando el botón ¿Olvidaste tu contraseña? en el formulario de entrada.

Si todo ha ido correctamente veremos un mensaje donde se nos informará de que nos han enviado una nueva contraseña a nuestro correo electrónico. En caso contrario, aparecerá un cuadro de error explicándonos los motivos causantes del fallo.

Perfil

En la pantalla de perfil podremos ver nuestros datos, y modificar la contraseña y el email de contacto, no sin antes haber introducido la contraseña actual, por temas de seguridad.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

26

Para modificar la contraseña o el correo electrónico tan solo deberemos rellenar los campos y pulsar en el botón Actualizar.

Menú de navegación

Según si nos encontramos identificados en el sistema o no, el menú superior de navegación variará de aspecto.

Si todavía no nos hemos identificado en el sistema veremos el siguiente menú, con un enlace a la página de bienvenida de la aplicación y otro al formulario de entrada.

Si por el contrario nos hemos identificado en el sistema podremos observar que aparecen nuevas opciones, dependiendo del tipo de usuario que seamos dentro de la aplicación, alumno, profesor o ambos a la vez.

La siguiente muestra es de un usuario que es profesor y a la vez alumno, para realizar pruebas.

Si pulsamos en el enlace Profesor se nos desplegará un submenú donde aparecerán todas las secciones disponibles, y pulsando en cualquiera de ellas nos dirigiremos a dicha sección.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

27

Además, en todas las secciones de gestión del profesor se encuentra una barra de acceso rápido que además de agilizar la navegación nos permitirá saber de un vistazo en que sección nos encontramos.

Panel profesor

El panel del profesor es lo primero que nos encontraremos al entrar en el sistema si somos un profesor. En el podemos encontrar todas las secciones de gestión necesarias para el completo uso del sistema.

Estas mismas secciones se encuentran en el menú desplegable de la barra superior, a excepción de la función Cambio de curso, ya que es una función más delicada que solo se debe usar para el cambio de un curso lectivo al siguiente.

Podemos volver en cualquier momento a él, pulsando en el enlace Panel dentro del menú Profesor situado en la barra superior.

Gestión de Profesores

En esta sección podremos añadir, editar y eliminar profesores del sistema.

Siempre debe existir al menos un profesor en el sistema, por lo que si somos el último profesor en la aplicación, no nos permitirá eliminarnos.

El sistema de gestión para todas las secciones es parecido, está compuesto por una tabla con varias opciones, tanto de edición como de búsqueda y ordenación.

1 2 3

4 5 6

7

8 9

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

28

Vamos a pasar a explicar cada una de las funciones que nos permite realizar dicha interfaz, en la siguientes tan solo explicaremos las nuevas funciones que vayas saliendo, ya que estas son equivalentes en todas las secciones.

1. Añadir: Si pulsamos en dicho enlace podremos añadir, en este caso un nuevo profesor. Tan solo deberemos introducir un nombre de usuario y un correo electrónico, opcional.

2. Editar: Si pulsamos en este enlace podremos editar algún profesor, que deberemos seleccionarlo con anterioridad pinchando en el recuadro de la izquierda de la tabla, a la izquierda del nombre de usuario. También se podrán editar los registros de cada uno de los listados, haciendo doble clic sobre el registro deseado.

Para todas las tablas de gestión de la aplicación, hacer doble click sobre un registro de la tabla implicará abrir el diálogo de edición del registro seleccionado.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

29

3. Eliminar: Pulsando éste enlace eliminaremos todos aquellos profesores que hayamos marcado anteriormente en la tabla, mediante sus recuadros. Si realmente deseamos hacer efectiva la eliminación tan solo deberemos de pulsar en el botón Eliminar del dialogo emergente.

4. Actualizar: Este botón permite actualizar el listado de profesores, por si en el transcurso de nuestra interacción o de otros profesores, el listado ha quedado desactualizado al estado real actual.

5. Navegador: Esta función nos permite cambiar de páginas, si se diese el caso de que en una solo página no entrasen todos los elementos a mostrar. Podemos especificar la página manualmente o ir pulsando en los botones de navegación.

6. Paginación: Esta función nos permite seleccionar cuál será el número de registros a mostrar en una misma página del listado.

7. Filtro: Los filtros nos permiten reducir el número de resultados a mostrar según los criterios que impongamos. Pueden ser de tipo texto o selección entre múltiples opciones.

8. Ordenación: Alguna columnas permiten, pulsando sobre su título, ordenar el listado por dicha columna, ascendente o descendentemente. Las columnas que son ordenables se muestran con un gradiente y las que no lo son con un color gris plano.

9. Selección múltiple: Marcando las diferentes filas podemos eliminar varias de golpe. Si marcamos el recuadro que se encuentra más arriba seleccionaremos/deseleccionaremos todos los registros que aparezcan en dicha página del listado.

Gestión de Alumnos

En esta sección podremos añadir, editar y eliminar alumnos del sistema.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

30

Podemos observar como tenemos filtros de cada una de las columnas para acelerar nuestras búsquedas, con tan solo escribir en el cuadro del filtro deseado y presionar Enter o perder el foco del campo, el listado se actualiza automáticamente con los resultados filtrados.

A la hora de añadir o editar deberemos rellenar los campos correctamente, en caso de que existiese algún error se nos mostraría un mensaje descriptivo para poder corregirlo.

Los procedimientos de navegación, paginación, ordenación y eliminación de alumnos son exactamente iguales que en el caso de la gestión de profesores, por lo que no se volverán a explicar.

Las nuevas funcionalidades propias de esta sección son las siguientes.

1 2

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

31

1. Importar alumnos: Esta función nos permitirá importar alumnos desde un fichero que debe cumplir unas normas, todos los datos de un mismo alumno deben estar en la misma fila, separados por comas (,) y con el siguiente formato: dni,usuario,apellidos,nombre. Pulsaremos en importar y al seleccionar el fichero nos mostrará en caso de éxito el número de alumnos importados.

2. Exportar alumnos: Esta función nos permite descargarnos todos aquellos usuarios que tengamos seleccionados a un fichero de texto plano, que sigue las mismas reglas que las impuestas para importar los alumnos.

Gestión de Esquemas

En esta sección podremos añadir, editar y eliminar esquemas del sistema.

Los procedimientos de filtración, navegación, paginación, ordenación y eliminación de esquemas son exactamente iguales que en los casos anteriores, por lo que no se volverán a explicar. Un esquema no se podrá eliminar si contiene ejercicios asociados en el sistema.

Las nuevas funcionalidades propias de esta sección son las siguientes.

1

1

2

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

32

1. Subir descripción: Este botón nos permite subir un fichero donde se explique detalladamente el esquema que se encuentre marcado, este fichero es de especial importancia para que los alumnos puedan realizar correctamente los ejercicios. No hay restricción de tipo para el fichero.

2. Ver descripción: Para los esquemas que tienen un fichero descriptivo subido al sistema podemos consultarlo pulsando simplemente en el enlace Ver

3. Subir PDF: Nos permite subir pulsando directamente en él un fichero de descripción de dicho esquema.

A la hora de querer añadir o editar un nuevo esquema, el sistema comprobará que puede realizar la conexión satisfactoriamente, por lo que deberemos tener configurada la red de manera apropiada.

Gestión de Ejercicios

En esta sección podremos añadir, editar y eliminar ejercicios del sistema.

Los procedimientos de filtración, navegación, paginación, ordenación y eliminación de ejercicios son exactamente iguales que en los casos anteriores, por lo que no se volverán a explicar.

A la hora de querer añadir o editar un nuevo ejercicio, el sistema comprobará que puede realizar la conexión con el esquema al que pertenece, por lo que deberemos tener configurada la red de manera apropiada, y además comprobará si la solución SQL es correcta sintácticamente hablando.

1 2

3 4 5

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

33

Las nuevas funcionalidades propias de esta sección son las siguientes.

1. Bloquear visibilidad ejercicios: Pulsando éste enlace bloquearemos todos aquellos ejercicios que hayamos marcado anteriormente en la tabla, mediante sus recuadros, para de esta manera asegurarnos que dichos ejercicios nunca aparezcan entre los ejercicios de repaso. Tras pulsar en el botón nos aparecerá un mensaje mostrando el número de ejercicios bloqueados.

2. Desbloquear visibilidad ejercicios: Pulsando éste enlace desbloquearemos todos aquellos ejercicios que hayamos marcado anteriormente en la tabla, mediante sus recuadros, para de esta manera puedan formar parte de los ejercicios de repaso

Los ejercicios que se encuentren asociados a una o varias prácticas no se mostrarán como ejercicios de repaso aunque éstos se encuentren visibles.

3. Importar ejercicios: Esta función nos permitirá importar ejercicios desde un fichero

XML que debe cumplir unas normas, un determinado DTD, a un esquema existente en el sistema. En caso de estar correctamente formado tratará de importar todos los ejercicios, comprobando la corrección sintáctica de cada uno de ellos, en caso de encontrar algún error se mostrará la descripción de éste y no se importará ningún ejercicio. En caso de éxito aparecerá un mensaje con el número de ejercicios importados a dicho esquema.

4. Exportar ejercicios: Esta función nos permite descargarnos todos aquellos ejercicios que pertenezcan al esquema deseado, el cual elegiremos en el desplegable que nos

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

34

aparecerá, pulsando en Descargar podremos guardar un fichero XML con los ejercicios.

5. Ejercicios en varias prácticas: En la columna práctica podremos observar, la práctica a la que pertenece un ejercicio, nada si dicho ejercicio no está asociado con ninguna práctica, o un asterisco “*” si dicho ejercicio se encuentra en varias prácticas. Para saber en qué prácticas exactamente podremos encontrar el ejercicio elegido tan solo tendremos que pasar el ratón por encima y se nos mostrarán en una etiqueta ordenados alfabéticamente.

Mediante el filtro de la columna Práctica, se podrán filtrar los ejercicios por las diferentes prácticas o por aquellos que no tengan practica asociada todavía.

El DTD a seguir para generar los XML para importar ejercicios deberá seguir las siguientes directrices:

Donde dificultad debe ser: facil, media o dificil . Si la etiqueta visible no se especifica el valor por defecto es FALSE (no visible para repasos).

A la hora de importar ejercicios desde el XML es conveniente usar las etiquetas CDATA para el campo query para evitar que el sistema pueda tratar algún fragmento de la consulta SQL como etiquetas XML.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

35

Gestión de prácticas

En esta sección podremos añadir, editar y eliminar prácticas del sistema.

Las prácticas que se encuentren activas (en realización) se mostrarán con la duración y con una cuenta atrás del tiempo restante, en la columna Duración.

Los procedimientos de filtración, navegación, paginación, ordenación y eliminación de prácticas son exactamente iguales que en los casos anteriores, por lo que no se volverán a explicar.

Una práctica solo se podrá modificar o eliminar si nunca ha sido solucionada por ningún alumno, si ya hubiese sido realizada por algún alumno tan solo se podría cambiar su estado de visibilidad, para permitir, o no, su realización. Los detalles de los ejercicios (enunciado, solución, etc.) sí que se podrán seguir modificando.

Desde los botones de añadir o editar práctica presentes en esta pantalla no se podrán asociar ejercicios a las prácticas, tan solo se podrán crear o editar el nombre, el número de la sesión a la que pertenece, y su visibilidad a la que se le proporcionará una duración en minutos para que transcurrido dicho tiempo, la práctica pase a estar bloqueada automáticamente.

1

2

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

36

La nueva opción que podemos destacar de la tabla es:

1. Ejercicios de práctica: Mediante este botón podemos acceder a la pantalla de edición detallada de una práctica en particular. El botón muestra como texto el número de ejercicios de los que dispone actualmente la práctica.

2. Tiempo restante: cuenta atrás dinámica del tiempo restante de realización de la práctica.

Edición detallada de práctica

En esta sección podremos ver, añadir, quitar ejercicios asociados a una práctica en concreto, así como reordenar los ejercicios dentro la práctica.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

37

Al entrar en dicha sección podemos observar cómo se nos muestran los datos de la práctica en la que nos encontramos, pero que no podremos editar a menos que pulsemos el botón Modificar datos de práctica que nos redirigirá a la pantalla de gestión de prácticas.

También tenemos dos listados, en el primero de ellos se muestran de manera ordenada los ejercicios que actualmente conforman la práctica.

En el segundo de los listados se nos muestran los ejercicios que se encuentran disponibles para añadir a la práctica.

1. Editar ejercicio: Permitirá editar los detalles del ejercicio seleccionado directamente desde la vista de confección de práctica, sin tener que buscarlo en la tabla de gestión de ejercicios.

2. Número de ordenación: Conforme vamos seleccionando varios ejercicios en el listado inferior para añadirlos a la práctica, observamos cómo se van añadiendo a cada ejercicio un número que representa la posición que ocuparía en la práctica, las posiciones se asignan dinámicamente, por lo que si una vez seleccionados varios ejercicios, se decide no incluir el seleccionado en primer lugar, los demás se reordenarían correctamente.

3. Añadir ejercicios a la práctica: Una vez que hemos seleccionado los ejercicios a añadir en el orden deseado tan solo deberemos pulsar el botón para añadir los ejercicios a la práctica. Ambos listados se actualizarán automáticamente mostrando el estado actual de la práctica. En caso de éxito se nos mostrará un mensaje con el número de ejercicios añadidos. De igual manera en caso de error se nos mostrará un mensaje con la causa.

4. Quitar ejercicios de la práctica: De igual manera que hicimos para añadir ejercicios a la práctica pero esta vez para quitarlos deberemos seleccionarlos del listado superior y pulsar en el botón Desvincular ejercicios de la práctica.

1

1

2

3

4

5

6

7

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

38

Quitar un ejercicio de una práctica no implica que el ejercicio se elimine del sistema, tan solo deja de formar parte de ésta, pero ese mismo ejercicio puede formar parte de otras prácticas o de la misma en un futuro.

5. Reordenar ejercicios de la práctica: Para reordenar los ejercicios dentro de la práctica será tan sencillo como pinchar en cualquier parte de la fila del ejercicio que deseamos recolocar y arrastrarlo a la posición deseada, esto podremos repetirlo con tantos ejercicios como queramos, pero para dar por terminada la operación de reordenación deberemos indicarle al sistema que deseamos guardar el orden que hemos establecido, para ello deberemos pulsar en el botón 6.

6. Guardar orden de ejercicios: Pulsando este botón guardaremos el orden en el que actualmente se ven los ejercicios en el listado.

7. Actualizar listado: Este botón sirve para actualizar los datos del listado al estado en que se encuentran en el sistema, es muy útil si se quiere volver al orden inicial de los ejercicios, en el caso de haber reordenado los ejercicios pero no haber guardado el orden con el botón 6.

Desde la pantalla de detalles de práctica es posible modificar directamente los detalles de un ejercicio en particular sin tener que dirigirse a la sección de ejercicios.

Gestión de entregas

En esta sección podremos descargarnos las entregas de las prácticas realizadas por los alumnos.

De igual manera que en el resto de listados de gestión de la aplicación, el profesor podrá marcar las sesiones de prácticas de las cuales quiere descargar sus entregas.

1

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

39

1. En la tabla además se muestra en número de entregas de alumnos por sesión de prácticas.

Las entregas correspondientes a una sesión son todas aquellas entregas de los alumnos a las prácticas con los números de sesión seleccionados. Cada alumno solo puede realizar una práctica correspondiente a la misma sesión.

El fichero PDF con las entregas seguirá el siguiente formato:

Cada entrega a una práctica realizada por un alumno aparecerá en una página o varias, pero nunca continuará la información de otra práctica en una misma página donde aparezcan datos de la anterior.

Las páginas con las entregas aparecen ordenadas por apellido y después por número de sesión, de esta manera todas las entregas de un mismo alumno aparecerán en páginas consecutivas

Un ejemplo de contenidos de una página del PDF correspondiente a una práctica realizada por un alumno.

1. Datos de entrega: Podemos observar como al comienzo de cada entrega aparecen los datos del alumno que la realizó, la sesión a la que corresponde, el nombre de la práctica, y la fecha y hora de su entrega.

2. Resumen: Más adelante observamos el número de ejercicios correcto, erróneos y sin contestar.

3. Soluciones detalladas por ejercicios: Por último aparecen los ejercicios, no se muestran los no contestados, con el orden que ocupan dentro de la práctica y si han sido correctamente resueltos o de manera errónea.

1

2

3

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

40

Cambio de curso

Esta función sirve para eliminar con un solo clic a todos los alumnos del sistema junto con sus entregas realizadas.

Esta función es únicamente para su uso tras finalizar un curso lectivo y dejar el sistema limpio de datos de alumnos para el próximo curso.

Éste es un proceso irreversible, por eso ha de tenerse cuidado de no pulsarlo por equivocación, es por ello que se encuentra oculto en un menú, situado en el panel principal del profesor, que deberemos desplegar previamente.

Una vez desplegado el menú y si estamos completamente seguros de la eliminación de todos los datos referentes a los alumnos del sistema, bastará con pulsar en el botón de Cambio de curso y confirmar el mensaje emergente que nos aparecerá.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

41

Anexo V - Manual de usuario del alumno

Este manual está destinado para aquellos usuarios de la aplicación que sean alumnos.

Login

Para poder entrar en el sistema hay que introducir unas credenciales antes, para ello hay que dirigirse a la sección de Login pulsando el botón Entrar situado en la parte superior derecha de la aplicación o desde el formulario que se encuentra en la propia página de inicio de la aplicación.

En el formulario de entrada procederemos a introducir nuestros datos, si se desconocen los datos de conexión en el primer uso de la aplicación, póngase en contacto con el profesor.

Si recordamos nuestros datos, tan solo faltará pulsar el botón Entrar. Si por el contrario hemos olvidado nuestra contraseña, podemos recuperarla desde el enlace ¿Olvidaste tu contraseña? Para recuperar la contraseña ver Recuperar contraseña.

Habilitar cuenta

Este paso tan sólo es necesario la primera vez que entra en el sistema, por lo que si usted ya ha entrado más de una vez puede pasar a la siguiente sección.

Esta sección aparece tras introducir exitosamente los datos de usuario y contraseña, y tiene la finalidad de permitirnos cambiar la contraseña que nos fue dada por defecto y especificar un correo electrónico de contacto, es importante verificar que el correo electrónico es válido ya que será la única manera que tendrás de recuperar la contraseña en caso de olvido.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

42

La contraseña no debe ser la misma que la que teníamos anteriormente, y se debe introducir dos veces para evitar errores a la hora de introducirla.

Tras rellenar el formulario, pulsaremos el botón Enviar y el sistema nos enviará al correo electrónico que le hemos proporcionado un link de activación para nuestra cuenta, el que deberemos visitar para poder activar la cuenta.

Tras visitar el link que se nos envió al correo electrónico, ya tendremos nuestra cuenta habilitada y lista para hacer uso del sistema con nuestra nueva contraseña.

En caso de que el sistema nos avise de que el link de activación es erróneo, puede ser debido a que un nuevo link de activación ha sido pedido con posterioridad, por lo que tan solo podremos activar la cuenta visitando el último link que se nos fue enviado.

Recuperar contraseña

Esta función nos permite recuperar la contraseña, en caso de haberla olvidado, para ello deberemos rellenar el formulario con nuestros datos, el nombre de usuario y el email de contacto que introdujimos durante la primera entrada al sistema.

Para llegar a la pantalla de Recuperar contraseña, se hace pulsando el botón ¿Olvidaste tu contraseña? en el formulario de entrada.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

43

Si todo ha ido correctamente veremos un mensaje donde se nos informará de que nos han enviado una nueva contraseña a nuestro correo electrónico.

En caso contrario, aparecerá un cuadro de error explicándonos las causas del fallo al recuperar la contraseña.

Perfil

En la pantalla de perfil podremos ver nuestros datos, y modificar la contraseña y el email de contacto, no sin antes haber introducido la contraseña actual, por temas de seguridad.

La pantalla de perfil para un alumno muestra los campos cuasi, DNI, nombre y apellidos del alumno, y correo electrónico.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

44

Para modificar la contraseña o el correo electrónico tan solo deberemos rellenar los campos y pulsar en el botón Actualizar.

Menú de navegación

Según si nos encontramos identificados en el sistema o no, el menú superior de navegación variará de aspecto.

Si todavía no nos hemos identificado en el sistema veremos el siguiente menú, con un enlace a la página de bienvenida de la aplicación y otro al formulario de entrada.

Si por el contrario nos hemos identificado en el sistema podremos observar que aparecen nuevas opciones, dependiendo del tipo de usuario que seamos dentro de la aplicación, alumno, profesor o ambos a la vez.

La siguiente muestra es de un usuario que es un alumno identificado.

Si pulsamos en el enlace Alumno se nos desplegará un submenú donde aparecerán las diferentes opciones que tiene disponibles un alumno.

Panel alumno

El panel del profesor es lo primero que nos encontraremos al entrar en el sistema si somos un alumno. En el podemos encontrar las funciones de realización de prácticas y realización de ejercicios de repaso.

Estas mismas secciones se encuentran en el menú desplegable de la barra superior.

Podemos volver en cualquier momento a él, pulsando en el enlace Panel dentro del menú de Alumno situado en la barra superior.

Desde el propio panel, además podremos saber cuál es el tiempo restante de realización de las prácticas activas gracias a que cada práctica lleva su propia cuenta atrás con el tiempo que le queda.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

45

Realización de ejercicios de repaso

Un alumno puede decidir realizar ejercicios de repaso, cuyos resultados no se guardan en la aplicación, por lo que no se tienen en cuenta a la hora de elaborar las notas de prácticas.

Para ello un alumno puede acceder mediante el enlace creado para tal efecto en el panel del Alumno.

Antes de comenzar a realizar los ejercicios, la aplicación nos da la opción de elegir diferentes criterios para poder generar una práctica de ejercicios de repaso lo más personalizada posible.

A continuación podemos ver todas las opciones que tiene a su disposición el usuario para filtrar los ejercicios a incluir, según sus preferencias.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

46

El alumno podrá especificar el número máximo de ejercicios que compondrán la práctica de repaso, las sesiones a las que pertenecen los ejercicios, los esquemas de bases de datos de dichos ejercicios y su dificultad.

Tras haber seleccionado los filtros deseados, el alumno podrá comenzar la realización de los ejercicios.

Para poder realizar los ejercicios de repaso, al alumno se le mostrará una pantalla como la que se muestra a continuación, donde se puede resolver un ejercicio, probarlo y guardarlo.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

47

En la parte superior de la interfaz observamos cómo nos muestra en que ejercicio del repaso nos encontramos, un enlace a la descripción del esquema y el SGBD al que pertenece.

En la pantalla de realización de un ejercicio encontramos varias opciones:

1. Descripción del esquema del ejercicio: Mediante este enlace podremos ver la descripción asociada que tiene el esquema al que pertenece el ejercicio que se está realizando. Es muy importante que los alumnos puedan ver la descripción del esquema sobre el que están trabajando, ya que en una misma práctica de ejercicios de repaso puede haber ejercicios pertenecientes a diferentes esquemas.

2. Editor de la solución: Editor donde el alumno podrá introducir su respuesta. El editor muestra el contenido coloreado según la sintaxis SQL y permite el uso de tabulaciones para que sea más cómodo el proceso de indentación.

3. Probar ejercicio: Mediante este botón, el alumno podrá probar su respuesta, recibiendo los resultados de la consulta y si ésta es correcta o no. Esta función es útil para asegurarse de la corrección de la solución propuesta por el alumno, antes de decidir guardarla.

El alumno también podrá probar el ejercicio mientras se encuentra escribiendo la respuesta sin necesidad de pulsar el botón de probar, simplemente con la combinación de teclas Ctrl+Enter.

1

2

3 4 5

6

7

8

9

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

48

4. Guardar ejercicio: Al pulsar este botón, el alumno estará guardando la solución dada para el ejercicio. Al igual que en el caso de Probar ejercicio, la respuesta será evaluada por la aplicación para devolver los resultados de la consulta y si es correcta o no. Al guardar el ejercicio, en la parte derecha de la interfaz el mensaje de estado del ejercicio cambiará a Ejercicio guardado en color verde, si se guardó sin errores, ó Ejercicio guardado con errores, en color rojo, si la respuesta fue guardada pero no era correcta.

De igual manera que ocurre con el botón de Probar, en este caso con la combinación de teclas Ctrl+S se podrá guardar el ejercicio.

5. Siguiente ejercicio: Mediante este botón el alumno podrá pasar a realizar el siguiente ejercicio de la práctica de repaso. Hay que tener en cuenta que si se pasa al siguiente ejercicio sin haber guardado la respuesta, ésta se perderá.

6. Estado del ejercicio: Esta etiqueta representa el estado del ejercicio. Un ejercicio puede encontrarse en tres estados diferentes. Ejercicio sin guardar, para los ejercicios sin una respuesta guardada,

representado con el color amarillo. Ejercicio guardado con errores, para los ejercicios cuya respuesta ha sido

guardada, pero dicha respuesta no era correcta. En este caso el color para la etiqueta será rojo.

Ejercicio guardado, para aquellos ejercicios cuya respuesta ha sido guardada y además era una respuesta correcta. En este caso el color para la etiqueta será verde.

7. Ver resumen: Mediante este botón podremos pasar a ver un resumen de todos los ejercicios del repaso así como nuestras respuestas y su corrección. Desde ésa interfaz también podremos descargarnos el resumen del repaso o volver a la realización de ejercicios si queremos continuar.

8. Navegador de ejercicios: En la parte superior de la interfaz de realización de un ejercicio, encontramos una serie de enlaces a cada uno de los ejercicios que componen la práctica, para poder movernos rápidamente a cualquiera de los ejercicios de ésta. Además podremos ver en todo momento en qué estado se encuentra cada ejercicio. Verde si es coincidente, rojo si es erróneo y amarillo/naranja si el ejercicio es coincidente pero el sistema ha generado advertencias o ayudas sobre su realización. El ejercicio actual se destaca mostrándolo más grande y en fondo blanco.

9. Abandonar repaso: Si deseamos abandonar el repaso, en cualquier momento podremos pulsar el enlace colocado en la parte superior derecha para tal efecto. Para evitar que salgamos del repaso de manera accidental, deberemos confirmar si realmente deseamos abandonar el repaso. Abandonar el repaso conlleva que se eliminarán los ejercicios guardados de éste.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

49

Resumen del repaso

Un alumno, tras haber realizado unos ejercicios de repaso, tiene la posibilidad de ver un resumen del mismo, donde se mostrarán todos los ejercicios y si se han respondido correctamente, incorrectamente, o no sea han contestado.

También podrá descargarse ese mismo resumen a un fichero para poder guardarlo. El fichero generado será un fichero PDF.

El alumno desde esta interfaz podrá decidir si da por terminado el repaso o desea volver para corregir alguno de los ejercicios guardados, mediante los enlaces que se encuentran en la parte superior de la pantalla.

Realización de práctica

La función principal que cumple un alumno en la aplicación es la realización de prácticas, para que puedan ser evaluadas sus habilidades a la hora de poner en práctica lo explicado en las clases de teoría.

Un alumno podrá iniciar la realización de una práctica, siempre y cuando dicha práctica se encuentre habilitada, y el alumno no haya entregado anteriormente una práctica correspondiente a la misma sesión de prácticas.

Las prácticas las debe habilitar el profesor y tienen una duración determinada que decidirá el profesor. Una vez que dicha duración ha concluido, la práctica quedará de nuevo inhabilitada y las realizaciones que se encontrasen en curso por los alumnos serán entregadas automáticamente. Si se da el caso de que durante la realización de la práctica,

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

50

ésta finaliza porque ha concluido su tiempo, al alumno se le mostrará el siguiente mensaje notificando la entrega automática de la práctica.

Para poder realizar los ejercicios que componen la práctica, al alumno se le mostrará una pantalla como la que se muestra a continuación, donde se puede resolver un ejercicio, probarlo y guardarlo.

1

2

3 4

5

7

7

8

10

6

9

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

51

En la parte superior de la interfaz observamos cómo nos muestra en que ejercicio de la práctica nos encontramos, un enlace a la descripción del esquema y el SGBD al que pertenece.

En la pantalla de realización de un ejercicio encontramos varias opciones:

1. Descripción del esquema del ejercicio: Mediante este enlace podremos ver la descripción asociada que tiene el esquema al que pertenece el ejercicio que se está realizando. Es muy importante que los alumnos puedan ver la descripción del esquema sobre el que están trabajando, ya que en una misma práctica puede haber ejercicios pertenecientes a diferentes esquemas.

2. Editor de la solución: Editor donde el alumno podrá introducir su respuesta. El editor muestra el contenido coloreado según la sintaxis SQL y permite el uso de tabulaciones para que sea más cómodo el proceso de indentación.

3. Probar ejercicio: Mediante este botón, el alumno podrá probar su respuesta, recibiendo los resultados de la consulta y si ésta es correcta o no. Esta función es útil para asegurarse de la corrección de la solución propuesta por el alumno, antes de decidir guardarla.

El alumno también podrá probar el ejercicio mientras se encuentra escribiendo la respuesta sin necesidad de pulsar el botón de probar, simplemente con la combinación de teclas Ctrl+Enter. De igual manera con la combinación Ctrl+S podrá guardar el ejercicio.

4. Guardar ejercicio: Al pulsar este botón, el alumno estará guardando la solución dada para el ejercicio. Al igual que en el caso de Probar ejercicio, la respuesta será evaluada por la aplicación para devolver los resultados de la consulta y si es correcta o no. Al guardar el ejercicio, en la parte derecha de la interfaz el mensaje de estado del ejercicio cambiará a Ejercicio guardado en color verde, si se guardó sin errores, ó Ejercicio guardado con errores, en color rojo, si la respuesta fue guardada pero no era correcta.

5. Mensajes de ayuda al alumno: Estos mensajes se mostrarán siempre que la aplicación detecte algún aspecto en la consulta enviada por el alumno que pueda ser corregido o mejorado.

6. Siguiente ejercicio: Mediante este botón el alumno podrá pasar a realizar el siguiente ejercicio de la práctica. Hay que tener en cuenta que si se pasa al siguiente ejercicio sin haber guardado la respuesta del ejercicio que se está realizando, ésta se perderá.

7. Estado del ejercicio: Esta etiqueta representa el estado del ejercicio. Un ejercicio puede encontrarse en tres estados diferentes. Ejercicio sin guardar, para los ejercicios sin una respuesta guardada,

representado con el color amarillo. Ejercicio guardado con errores, para los ejercicios cuya respuesta ha sido

guardada, pero dicha respuesta no era correcta. En este caso el color para la etiqueta será rojo.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

52

Ejercicio guardado, para aquellos ejercicios cuya respuesta ha sido guardada y además era una respuesta correcta. En este caso el color para la etiqueta será verde.

8. Navegador de ejercicios: En la parte superior de la interfaz de realización de un ejercicio, encontramos una serie de enlaces a cada uno de los ejercicios que componen la práctica, para poder movernos rápidamente a cualquiera de los ejercicios de ésta. Además podremos ver en todo momento en qué estado se encuentra cada ejercicio. Verde si es coincidente, rojo si es erróneo y amarillo/naranja si el ejercicio es coincidente pero el sistema ha generado advertencias o ayudas sobre su realización. El ejercicio actual se destaca mostrándolo más grande y en fondo blanco.

9. Enviar práctica: Cuando deseemos entregar los ejercicios guardados durante el transcurso de la práctica podremos pulsar este botón situado en la esquina superior derecha. Antes de enviar la práctica nos mostrará un pequeño resumen de lo que vamos a entregar y nos pedirá la confirmación para evitar entregas accidentales.

10. Abandonar práctica: Si deseamos abandonar la práctica, en cualquier momento podremos pulsar el botón desplegable situado junto al botón de enlace colocado en la parte superior derecha para tal efecto. Para evitar que salgamos de la práctica de manera accidental, deberemos confirmar si realmente deseamos abandonar la práctica. Abandonar la práctica conlleva que se eliminarán los ejercicios guardados de ésta, esto no quita que más adelante se puede volver a iniciar desde el principio si aún continúa habilitada.

Resumen de la práctica

Un alumno, tras haber realizado una práctica, tiene la posibilidad de ver un resumen de la misma, antes de enviarla definitivamente, donde se mostrarán todos los ejercicios y si se han respondido correctamente, incorrectamente, o no sea han contestado.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

53

También podrá descargarse ese mismo resumen a un fichero para poder guardarlo. El fichero generado será un fichero PDF.

Anexos TFG | Diego Díez Reingeniería de la aplicación de realización de prácticas de Bases de Datos

54