Trabajo Fin de Grado
Ingeniería de Telecomunicación
Herramienta de Evaluación Automática mediante
Bases de Batos NoSQL aplicando Métrica v3
Autor: Andrés Martínez Gotor
Tutor: Antonio Jesús Sierra Collado
Dep. Ingeniería Telemática
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2014
Proyecto Fin de Carrera
Ingeniería de Telecomunicación
Herramienta de Evaluación Automática mediante
Bases de Batos NoSQL aplicando Métrica v3
Autor:
Andrés Martínez Gotor
Tutor:
Antonio Jesús Sierra Collado
Profesor titular
Dep. de Ingeniería Telemática
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2014
Proyecto Fin de Carrera: Herramienta de Evaluación Automática mediante Bases de Batos NoSQL
aplicando Métrica v3
Autor: Andrés Martínez Gotor Tutor: Antonio J. Sierra Collado
El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros:
Presidente:
Vocales:
Secretario:
Acuerdan otorgarle la calificación de:
Sevilla, 2013
El Secretario del Tribunal
Índice
BLOQUE 0. Introducción ................................................................................................................ 3
Objetivo del proyecto ................................................................................................................ 3
Alcance del proyecto ................................................................................................................. 3
BLOQUE 1. Estudio de la situación actual ..................................................................................... 4
Herramientas de asistencia a la evaluación. E-assessment ...................................................... 4
Introducción .......................................................................................................................... 4
Plataforma de enseñanza virtual .......................................................................................... 4
Herramienta del Departamento de Ingeniería Telemática ................................................... 5
Aplicación de e-assessment .................................................................................................. 6
Bases de datos no relacionales ................................................................................................. 7
Introducción .......................................................................................................................... 7
MongoDB............................................................................................................................... 7
Software de detección de plagio ............................................................................................... 9
BLOQUE 2. Aplicación MÉTRICA Versión 3 .................................................................................. 10
Introducción a MÉTRICA Versión 3 ......................................................................................... 10
Procesos principales de MÉTRICA Versión 3 ........................................................................... 11
Estudio de la viabilidad del sistema (EVS) ............................................................................... 12
ACTIVIDAD EVS 1: ESTABLECIMIENTO DEL ALCANCE DEL SISTEMA .................................... 12
ACTIVIDAD EVS 2: ESTUDIO DE LA SITUACIÓN ACTUAL ...................................................... 16
ACTIVIDAD EVS 3: DEFINICIÓN DE REQUISITOS DEL SISTEMA ............................................ 19
ACTIVIDAD EVS 4: ESTUDIO DE ALTERNATIVAS DE SOLUCIÓN ........................................... 23
ACTIVIDAD EVS 5: VALORACIÓN DE LAS ALTERNATIVAS .................................................... 24
ACTIVIDAD EVS 6: SELECCIÓN DE LA SOLUCIÓN ................................................................. 25
Análisis del Sistema de Información (ASI) ............................................................................... 25
ACTIVIDAD ASI 1: DEFINICIÓN DEL SISTEMA ....................................................................... 26
ACTIVIDAD ASI 2: ESTABLECIMIENTO DE REQUISITOS ........................................................ 28
ACTIVIDAD ASI 3: IDENTIFICACIÓN DE SUBSISTEMAS DE ANÁLISIS .................................... 34
ACTIVIDAD ASI 4: ANÁLISIS DE LOS CASOS DE USO ............................................................ 36
ACTIVIDAD ASI 5: ANÁLISIS DE CLASES................................................................................ 37
ACTIVIDAD ASI 8: DEFINICIÓN DE INTERFACES DE USUARIO .............................................. 40
ACTIVIDAD ASI 9: ANÁLISIS DE CONSISTENCIA Y ESPECIFICACIÓN DE REQUISITOS ........... 41
ACTIVIDAD ASI 10: ESPECIFICACIÓN DEL PLAN DE PRUEBAS .............................................. 42
Diseño del Sistema de Información (DSI) ................................................................................ 43
1 – Índice – Objetivo del proyecto
ACTIVIDAD DSI 1: DEFINICIÓN DE LA ARQUITECTURA DEL SISTEMA .................................. 43
ACTIVIDAD DSI 2: DISEÑO DE LA ARQUITECTURA DE SOPORTE ......................................... 46
ACTIVIDAD DSI 3: DISEÑO DE CASOS DE USO REALES ........................................................ 46
ACTIVIDAD DSI 4: DISEÑO DE CLASES ................................................................................. 49
ACTIVIDAD DSI 6: DISEÑO FÍSICO DE DATOS ....................................................................... 52
ACTIVIDAD DSI 7: VERIFICACIÓN Y ACEPTACIÓN DE LA ARQUITECTURA DEL SISTEMA ..... 53
ACTIVIDAD DSI 8: GENERACIÓN DE ESPECIFICACIONES DE CONSTRUCCIÓN ..................... 54
ACTIVIDAD DSI 9: DISEÑO DE LA MIGRACIÓN Y CARGA INICIAL DE DATOS ....................... 55
ACTIVIDAD DSI 10: ESPECIFICACIÓN TÉCNICA DEL PLAN DE PRUEBAS ............................... 56
ACTIVIDAD DSI 11: ESTABLECIMIENTO DE REQUISITOS DE IMPLANTACIÓN ...................... 59
ACTIVIDAD DSI 12: APROBACIÓN DEL DISEÑO DEL SISTEMA DE INFORMACIÓN ............... 60
Construcción del Sistema de Información .............................................................................. 60
ACTIVIDAD CSI 1: PREPARACIÓN DEL ENTORNO DE GENERACIÓN Y CONSTRUCCIÓN ...... 61
ACTIVIDAD CSI 2: GENERACIÓN DEL CÓDIGO DE LOS COMPONENTES Y PROCEDIMIENTOS
............................................................................................................................................. 61
ACTIVIDAD CSI 3: EJECUCIÓN DE LAS PRUEBAS UNITARIAS ............................................... 61
ACTIVIDAD CSI 4: EJECUCIÓN DE LAS PRUEBAS DE INTEGRACIÓN ..................................... 62
ACTIVIDAD CSI 5: EJECUCIÓN DE LAS PRUEBAS DEL SISTEMA ............................................ 63
ACTIVIDAD CSI 6: ELABORACIÓN DE LOS MANUALES DE USUARIO ................................... 64
ACTIVIDAD CSI 7: DEFINICIÓN DE LA FORMACIÓN DE USUARIOS FINALES ........................ 64
ACTIVIDAD CSI 8: CONSTRUCCIÓN DE LOS COMPONENTES Y PROCEDIMIENTOS DE
MIGRACIÓN Y CARGA INICIAL DE DATOS ............................................................................ 64
ACTIVIDAD CSI 9: APROBACIÓN DEL SISTEMA DE INFORMACIÓN...................................... 64
Implantación y Aceptación del Sistema (IAS) .......................................................................... 64
ACTIVIDAD IAS 1: ESTABLECIMIENTO DEL PLAN DE IMPLANTACIÓN ................................. 65
ACTIVIDAD IAS 2: FORMACIÓN NECESARIA PARA LA IMPLANTACIÓN ............................... 66
ACTIVIDAD IAS 3: INCORPORACIÓN DEL SISTEMA AL ENTORNO DE OPERACIÓN .............. 66
ACTIVIDAD IAS 4: CARGA DE DATOS AL ENTORNO DE OPERACIÓN ................................... 66
ACTIVIDAD IAS 5: PRUEBAS DE IMPLANTACIÓN DEL SISTEMA ........................................... 66
ACTIVIDAD IAS 6: PRUEBAS DE ACEPTACIÓN DEL SISTEMA ................................................ 67
ACTIVIDAD IAS 9: PRESENTACIÓN Y APROBACIÓN DEL SISTEMA ....................................... 67
BLOQUE 3. Desarrollo del proyecto ............................................................................................ 69
Visión general .......................................................................................................................... 69
Cliente para la PFED ............................................................................................................ 70
Cliente para el examen ........................................................................................................ 74
2 – Índice – Objetivo del proyecto
Servidor ............................................................................................................................... 74
Control de plagio ................................................................................................................. 81
BLOQUE 4. Pruebas de ejecución ................................................................................................ 83
Servidor ................................................................................................................................... 83
Cliente para la PFED ................................................................................................................ 83
Cliente para el examen ............................................................................................................ 85
Obtención de notas y detección de plagio .............................................................................. 86
BLOQUE 5. Conclusiones y bibliografía ....................................................................................... 88
Conclusiones y líneas futuras de trabajo ................................................................................ 88
Bibliografía .............................................................................................................................. 89
Resumen .................................................................................................................................. 92
BLOQUE 6. Anexos ...................................................................................................................... 93
Anexo 1. Manuales de usuario ................................................................................................ 93
Instrucciones corrector PFED .............................................................................................. 93
Instrucciones para la instalación y ejecución del servidor .................................................. 95
Instrucciones para el sistema de control de plagio ............................................................. 95
Anexo 2. Código fuente ........................................................................................................... 96
Corrector PFED .................................................................................................................... 96
Corrector Examen ............................................................................................................. 111
Servidor ............................................................................................................................. 125
Control de plagio ............................................................................................................... 146
3 – BLOQUE 0. Introducción – Objetivo del proyecto
BLOQUE 0. Introducción Objetivo del proyecto El objetivo de este proyecto es desarrollar un software de asistencia a la evaluación. Este
software se aplicará a la asignatura de Fundamentos de Programación II. Su objetivo es
ofrecer a los alumnos una plataforma para la corrección, de manera automática, de la
Práctica Final de Estructuras Dinámicas (PFED).
El producto final va destinado a los alumnos y profesores de la asignatura, por lo que es
necesario que la herramienta sea sencilla de utilizar para los alumnos y que permita
funcionalidades más avanzadas para los profesores.
Alcance del proyecto Este proyecto se divide en 7 bloques. En este primer bloque se realiza la introducción al
proyecto que vamos a realizar.
En segundo lugar se realizará el estudio de la situación actual. Se aportará una visión
general de las herramientas utilizadas en este proyecto. Para ello se estudiarán algunas
herramientas de evaluación automática, el uso de base de datos no relacionales, en
particular MongoDB y algunas herramientas de control de plagio.
El segundo bloque tratará sobre el diseño e implementación del software realizado. Para
realizar este bloque se seguirá la metodología de MÉTRICA Versión 3 [1] con la que se
describirá con detalle el proceso de especificación de requisitos, diseño del sistema, plan
de pruebas y la ejecución del mismo.
En el siguiente bloque especificaremos en detalle cuáles han sido los pasos realizados
para el desarrollo y codificación del proyecto. A continuación mostraremos el resultado
de las pruebas de ejecución del mismo, y finalmente realizaremos la extracción de
conclusiones y líneas futuras de trabajo, además de las referencias bibliográficas.
Por último se efectuará un bloque con los anexos del proyecto. En ellos se detallarán los
manuales de usuario para las herramientas desarrolladas, así como el código
correspondiente.
4 – BLOQUE 1. Estudio de la situación actual – Herramientas de asistencia a la
evaluación. E-assessment
BLOQUE 1. Estudio de la situación actual Herramientas de asistencia a la evaluación. E-assessment
Introducción En la actualidad, las herramientas de asistencia a la evaluación se utilizan en casi
cualquier ámbito de la enseñanza. Definimos e-assessment [2] como cualquier
asistencia a un proceso de evaluación mediante el uso de las tecnologías de la
información y la comunicación (TIC). En el ámbito que nos ocupa, el e-assessment abarca
desde procesadores de texto y otras herramientas para el diseño de evaluaciones hasta
herramientas de corrección automática y monitorización de estudiantes.
Dependiendo de la naturaleza de la asistencia podemos definir dos tipos de actividades:
evaluación asistida por computación, en la que la evaluación se delega en parte a las TIC,
o evaluación basada en computación, cuando la totalidad de la evaluación se realiza
mediante herramientas informáticas.
Entre los beneficios del uso de la evaluación asistida [3][4] podemos destacar:
Mayor capacidad de procesamiento. Lo que se traduce en la posibilidad de
evaluar a un mayor número de alumnos.
Menor coste de la evaluación. La evaluación se realiza de forma automática
reduciéndose costes en personal y horas de trabajo.
Mayor precisión. La evaluación realizada de manera automática es más fiable en
cuanto a errores de puntuación.
Mayor flexibilidad. La evaluación puede realizarse en cualquier momento
dependiendo de la disponibilidad del alumno evaluado.
Respuesta inmediata. El proceso de obtención de notas es inmediato, por lo
tanto, los estudiantes pueden conocer su nota justo después de realizar su
evaluación.
Interactividad. El uso de esta tecnología permite que en un examen exista
comunicación entre evaluador y evaluado.
Disponibilidad geográfica. No es necesario que los estudiantes se personifiquen
físicamente en un emplazamiento para poder ser evaluados.
Correcciones complejas. Gracias al proceso computacional es posible realizar
operaciones más complejas para medir distintos aspectos. Por ejemplo, para la
evaluación de un software se puede medir el rendimiento ofrecido.
Plataforma de enseñanza virtual En la Universidad de Sevilla el método más extendido para la asistencia a la evaluación
es la plataforma de Enseñanza Virtual [5]. En la actualidad se encuentra disponible la
versión 3. Esta plataforma ofrece un amplio conjunto de funcionalidades como es el uso
compartido de ficheros, la publicación de anuncios y notas, la utilización de calendarios
para la planificación de las asignaturas y la publicación de foros entre otros.
5 – BLOQUE 1. Estudio de la situación actual – Herramientas de asistencia a la
evaluación. E-assessment
Otra de las funcionalidades de la plataforma es la asistencia a la evaluación de las
asignaturas. Para ello los profesores pueden:
Publicar tareas. En estas tareas los alumnos pueden subir ficheros, realizar
comentarios y responder a todo lo requerido en el enunciado de la misma. Esto
debe realizarse en el periodo de tiempo estipulado por el docente en la tarea.
Una vez finalizado, el profesor debe evaluar las tareas individualmente.
Realizar exámenes. Estos exámenes se realizan de manera telemática. Existen
distintos procesos para la operación y seguridad que permiten tanto la fiabilidad
en estos exámenes como la protección con contraseña, el establecimiento de
tiempos límite para su realización o la ordenación aleatoria de preguntas y
respuestas. La principal limitación de este sistema es que para que puedan ser
evaluados automáticamente, los exámenes deben ser evaluaciones tipo test o
de preguntas cortas en la que solo existe una respuesta válida.
Para nuestro proyecto requeriremos una evaluación de un material más complejo. En
nuestro caso necesitaremos evaluar tanto el código fuente realizado para la Práctica
Final de Estructuras Dinámicas (PFED) como el examen posterior en el que se requerirán
modificaciones sobre el código antes realizado. Esta tarea es realizada por los alumnos
de la asignatura de Fundamentos de Programación 2 (FP2) del Grado de Ingeniería de
las Tecnologías de Telecomunicación de la Universidad de Sevilla [6][7].
La corrección de este código no se puede realizar mediante la Enseñanza Virtual, ya que
es necesario que el código en cuestión se compile, ejecute y pase una serie de pruebas.
En la actualidad hay casi 300 alumnos matriculados en la asignatura, de modo que
también se descarta la corrección individual de cada uno de los trabajos manualmente.
Es necesaria la utilización de otra herramienta para que esta evaluación sea viable y
eficiente.
Herramienta del Departamento de Ingeniería Telemática Para la realización de la tarea de corregir el código fuente, el profesorado del
Departamento de Telemática (encargado de impartir la asignatura de FP2) ha
desarrollado una herramienta [8][9] cuyo objetivo es comprobar la correcta realización
de este código. Para ello, dados unos ficheros de configuración, la herramienta compila
y ejecuta el código de los alumnos. Como resultado de esta operación, la herramienta
genera una salida de texto por pantalla y un fichero de texto con un informe sobre la
gestión de la memoria dinámica.
El texto que se muestra en la pantalla nos indica si el código fuente realizado por el
alumno es correcto en cuanto a la funcionalidad. Es decir, nos indica si dados los ficheros
de entrada correspondientes, los ficheros de salida generados por el código del alumno
son correctos.
Es importante destacar que el código requerido en la PFED está escrito en lenguaje de
programación C. En este lenguaje la gestión de la memoria dinámica [10] debe realizarse
6 – BLOQUE 1. Estudio de la situación actual – Herramientas de asistencia a la
evaluación. E-assessment
manualmente. Es por este motivo por el que la herramienta genera, además, un informe
en el que se detalla si el alumno ha realizado la gestión de memoria correctamente o
no.
La principal limitación de esta herramienta es que debe ejecutarse de manera local y
uno por uno para cada alumno presentado. Para agilizar esta tarea pueden codificarse
pequeños scripts que ejecuten la herramienta para cada trabajo del alumno, sin
embargo, no es un sistema idóneo, ya que la representación de resultados resulta difícil
de interpretar.
No obstante aún quedan varios aspectos por cubrir:
La corrección del examen posterior a la práctica con las modificaciones
requeridas también debe hacerse de manera automática. Para ello, en la
actualidad se ejecutan otros scripts que indicaban solo si la salida del programa
había sido correcta o no.
La evaluación debe hacerse de manera telemática. Hasta ahora los alumnos
pasaban las pruebas de manera local en su equipo y subían los ficheros
correspondientes a la plataforma de Enseñanza Virtual para que los profesores
pudiesen evaluarlo. Es conveniente desarrollar una plataforma que realice todas
estas acciones de manera unificada.
La generación de la calificación convendría que fuera automática. Como ya
hemos comentado, la precisión y eficacia obtenida si la calificación la realiza un
sistema autónomo es mayor que la obtenida del personal humano.
Para abordar algunas de estas limitaciones existe una solución desarrollada por un
antiguo alumno de la Escuela Superior de Ingeniería.
Aplicación de e-assessment El antiguo alumno Sergio Bellido, como parte de su proyecto final de carrera [11],
desarrolló un sistema para la corrección automática de la Práctica Final de Programación
Orientada a Objetos (PFPOO) de la misma asignatura FP2.
En este caso, la estructura del sistema es algo diferente a lo que se pretende con este
proyecto, ya que en esta práctica se cambia la forma de realizar las pruebas y no se
comprueba la gestión de memoria.
Además, en este proyecto solo se considera el escenario del examen, en lugar de los dos
escenarios que tendremos en nuestro proyecto (la corrección de la práctica previa al
examen y el examen mismo). En el desarrollo de la metodología de MÉTRICA Versión 3,
se analizarán las opciones de reutilización posibles.
7 – BLOQUE 1. Estudio de la situación actual – Bases de datos no relacionales
Bases de datos no relacionales
Introducción Uno de los aspectos más importantes del sistema de nuestro proyecto es el
almacenamiento persistente de los datos. Para ir recogiendo los resultados y las notas
de los alumnos necesitaremos utilizar un gestor de base de datos.
En [12][13] disponemos de comparativas entre los gestores de bases de datos
relacionales clásicos como MySQL y los recientes gestores orientados a objetos o
documentos como MongoDB. En estas comparativas vemos cómo MongoDB, que se
aleja de los esquemas clásicos de bases de datos relacionales con lenguaje SQL, ofrece
tanto una mayor escalabilidad horizontal, como un mejor rendimiento. Esta mejora de
rendimiento se traduce en menores tiempos de inserción, selección y actualización de
los datos.
Por lo tanto, y para continuar con el trabajo de Sergio Bellido, elegiremos el gestor de
base de datos MongoDB para nuestro proyecto. A continuación, pasamos a comentar
algunos aspectos importantes de este gestor.
MongoDB MongoDB [14] (su nombre proviene de “humongous”, gigantesco) es una base de datos
de código abierto basado en documentos. Está escrita en C++ y se define a sí misma
como el líder de las bases de datos NoSQL (Not only SQL).
Entre sus características más importantes podemos destacar:
Está orientada a documentos. Estos documentos siguen el estilo JSON [15]. Los
documentos siguen esquemas dinámicos, en lugar de las tablas estáticas del
lenguaje SQL.
Permite la replicación de datos usando un grupo de procesos del demonio
principal. Con ello se consigue redundancia y una alta disponibilidad de la
información [16].
Ofrece escalabilidad horizontal sin perder funcionalidad [17]. Es lo que se
denomina el proceso de Sharding y permite que, ante el crecimiento de la
necesidad de almacenamiento de datos, se pueda aumentar la capacidad de
procesamiento añadiendo nuevas máquinas y siguiendo una arquitectura
horizontal, no jerárquica.
Para poder comenzar a utilizar esta base de datos, es necesario conocer algunas
características sobre su organización y sintaxis. Toda la información mostrada en este
documento puede ampliarse siguiendo el manual online [18] que se encuentra
disponible en su página oficial.
Como ya hemos comentado, MongoDB está orientada a documentos. Un documento
[19] no es más que la unidad de almacenamiento de un objeto JSON. Los datos del
documento están organizados en parejas campo-valor. Sin embargo un valor puede ser
8 – BLOQUE 1. Estudio de la situación actual – Bases de datos no relacionales
a su vez una lista u otro documento. Un ejemplo de un documento puede verse en la
figura 1.
Figura 1. Documento JSON.
Los documentos en MongoDB, a su vez, se agrupan en colecciones (collections). Una
colección es un conjunto de documentos que comparten un mismo índice. Es lo análogo
a una tabla en el esquema de datos relacional.
La sintaxis básica para realizar una operación es la siguiente:
db.users.find( { age: { $gt : 18 } }).sort( { age : 1 } )
En el ejemplo, users es la colección a utilizar y find es la opción a realizar. Con ello
buscamos obtener de la colección users todos los documentos que cumplan una
condición. A continuación, entre paréntesis, especificamos siguiendo el estilo JSON, que
la condición que debe cumplir un documento para que se muestre es que el valor de la
variable age sea mayor o igual a 18. Finalmente, añadimos un modificador a la
sentencia para que se nos muestren los documentos por orden creciente utilizando
como índice el campo age.
Para insertar y modificar un documento, la sintaxis es parecida. A la hora de insertar un
documento, debemos especificar el documento en formato JSON, y para modificar un
documento, basta con especificar el valor a modificar:
db.users.insert( { name: "sue",
age: 26,
status: "A",
groups: [ "news" , "sport" ] } )
db.users.update( { name: "sue" }, { $set: { age: 27 } } )
9 – BLOQUE 1. Estudio de la situación actual – Software de detección de plagio
Software de detección de plagio Una vez que se ha recibido el trabajo de los estudiantes, debido a que la corrección se
realiza de manera automática, sería conveniente realizar cierto control para asegurar
que el código fuente de los alumnos no es resultante del plagio total o parcial del código
de otro alumno.
En [20] podemos ver una comparativa entre algunas de las herramientas software de
detección de plagio que existen en la actualidad. De las expuestas en [20], podríamos
elegir varias como MOSS y JPlag, pero por su sencillez y buenos resultados, en este
proyecto utilizaremos el software “similarity tester SIM” [21].
Se trata del código abierto desarrollado por el profesor Dick Grune del departamento de
Ciencias Computacionales de la Universidad Ámsterdam. Es compatible con varios
lenguajes de programación, entre ellos C y Java, que son los lenguajes utilizados en la
asignatura de FP2.
En su manual de usuario [22], se especifica la sintaxis para la ejecución y expone que
una similitud entre dos ficheros mayor del 30 % se considera relevante, y que un valor
inferior al 20% puede ser una coincidencia. Un ejemplo de ejecución es el siguiente:
sim_text -e -p -s new/* / old/*
Con esta sentencia se compararían todos los ficheros de la carpeta new con los de la
carpeta old y se reportaría si alguna de las parejas de ficheros tiene una similitud mayor
del 20%.
En este bloque hemos estudiado algunas de las distintas herramientas de asistencia a la
evaluación que tenemos disponibles para el proyecto que nos ocupa. Hemos analizado
las bases de datos no relaciones, en especial MongoDB, para estudiar sus características
y sintaxis. Finalmente, hemos realizado una visión general sobre herramientas de
control de plagio y en particular sobre el software SIM.
Una vez realizado el estudio previo, estamos en condiciones de iniciar el proceso de
planificación y análisis del proyecto que vamos a realizar. Para ello seguiremos la
metodología de MÉTRICA Versión 3.
10 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Introducción a MÉTRICA Versión 3
BLOQUE 2. Aplicación MÉTRICA Versión 3 Introducción a MÉTRICA Versión 3 MÉTRICA Versión 3 [1] es una metodología que ofrece a las organizaciones un
instrumento para poder sistematizar las actividades del ciclo de vida del software. Los
principales objetivos que se pretenden conseguir con la aplicación de esta metodología
son:
Proporcionar o definir los Sistemas de Información de una organización
aplicando un marco estratégico de desarrollo.
Que los productos software de la organización satisfagan las necesidades de los
usuarios haciendo hincapié en el análisis de requisitos.
Mejorar la productividad de los departamentos de Sistemas y Tecnologías de
Información y Comunicación, facilitando la adaptación a cambios y la
reutilización de lo que sea posible.
Facilitar las tareas de comunicación para mejorar el entendimiento entre los
participantes en el ciclo de vida del proyecto.
Facilitar la operación y mantenimiento de los productos desarrollados.
Esta metodología se basa en la versión 2.1 de MÉTRICA pero está enfocado en la división
del desarrollo en Procesos. Los Procesos principales de MÉTRICA Versión 3 son: el
Proceso de Planificación, el Proceso de Desarrollo y el Proceso de Mantenimiento.
MÉTRICA Versión 3 cubre dos tipos de desarrollo: sistemas estructurados y sistemas
orientados a objetos. Además facilita, a través de interfaces, la realización de otros
procesos de apoyo como la Gestión de Proyectos, la Gestión de Configuración y el
Aseguramiento de Calidad y Seguridad.
Para desarrollar los distintos Procesos, se sigue el modelo propuesto en la norma ISO
12.207 “Information technology – Software life cycle processes”. De esta norma se
obtiene la estructura de MÉTRICA Versión 3.
En el documento de Aportaciones de Métrica Versión 3 [22] se detalla que, además de
la norma ISO 12.207, entre los estándares de referencia para la especificación de la
metodología se deben destacar las normas ISO/IEC TR 15.504/SPICE “Software Process
Improvement and Assurance Standards Capability Determination”, UNE-EN-ISO
9001:2000 Sistemas de Gestión de la Calidad. Requisitos, UNE-EN-ISO 9000:2000
Sistemas de Gestión de la Calidad. Fundamentos y Vocabulario y el estándar IEEE 610.12-
1.990 “Standard Glossary of Software Engineering Terminology”. También se detalla que
se han tenido en cuenta otras metodologías como SSADM, Merise, Information
Engineering, MAGERIT. Metodología de Análisis y Gestión de Riesgos de los Sistemas de
Información promovida por el Consejo Superior de Informática y EUROMÉTODO.
11 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Procesos principales de MÉTRICA
Versión 3
Procesos principales de MÉTRICA Versión 3 Como ya hemos introducido, MÉTRICA Versión 3 se divide en 3 procesos:
Proceso de Planificación de Sistemas de Información (PSI). Este proceso no está
incluido en la norma ISO 12.207. Su principal objetivo es proporcionar un marco
estratégico de referencia para los Sistemas de Información. Con ello se pretende
orientar las actuaciones de la organización responsable del proyecto, apoyando
la estrategia corporativa. Para ello se elabora una arquitectura de información y
un plan de proyectos informáticos que dan apoyo a los objetivos estratégicos.
Como resultado de este proceso de obtiene:
o Un catálogo de requisitos del PSI, surgido del estudio de la situación
actual en caso de que sea significativo.
o La arquitectura de información.
Desarrollo de Sistemas de Información (DSI). Contiene todas las actividades y
tareas que se deben llevar a cabo para desarrollar un sistema. Este proceso cubre
desde el análisis de requisitos hasta la instalación del software. Se divide en las
siguientes actividades:
o Estudio de la Viabilidad del Sistema (EVS).
o Análisis del Sistema de Información (ASI).
o Diseño del Sistema de Información (DSI).
o Construcción del Sistema de Información (CSI).
o Implantación y Aceptación del Sistema (IAS).
Detallaremos cada una de estas actividades junto con su aplicación a nuestro
proyecto en los siguientes apartados.
Mantenimiento de Sistemas de Información (MSI). El objetivo de este proceso
es la obtención de una nueva versión de un sistema de información desarrollado
con MÉTRICA, a partir de las peticiones de mantenimiento de los usuarios finales
debidos a problemas detectados en el sistema o por la necesidad de mejora del
mismo.
En ese proceso solo se consideran el Mantenimiento Correctivo y Evolutivo. Los
productos que se obtienen de este proceso son:
o Catálogo de peticiones de cambio.
o Resultado del estudio de la petición.
o Propuesta de solución.
o Análisis de impacto de los cambios.
o Plan de acción para la modificación.
o Plan de pruebas de regresión.
o Evaluación del cambio.
o Evaluación del resultado de las pruebas de regresión.
En nuestro proyecto partimos de una arquitectura de información ya establecida y
tratamos el desarrollo inicial de un sistema de información, por lo que a continuación
12 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
detallaremos cada una de las actividades que forman el proceso de Desarrollo de
Sistemas de Información (DSI).
Estudio de la viabilidad del sistema (EVS) Este proceso [28] trata el estudio de un conjunto concreto de necesidades para
proponer una solución a corto plazo que tenga en cuenta las restricciones existentes, ya
sean económicas, técnicas, legales u operativas.
Se realiza un estudio de la situación actual y de los requisitos planteados. Después se
estudian diferentes alternativas para la solución.
Una vez descritas cada una de las alternativas, se valora su impacto, la inversión
necesaria y los riesgos asociados. Esta información se analiza y se selecciona la más
adecuada.
Las actividades que engloba este proceso se recogen en la figura 2. A continuación se
detallará/se detalla cada una de ellas.
Figura 2. Proceso EVS
ACTIVIDAD EVS 1: ESTABLECIMIENTO DEL ALCANCE DEL SISTEMA
El objetivo de este apartado es analizar el conjunto concreto de necesidades y
restricciones (económicas, técnicas, legales y operativas), para realizar una propuesta a
corto plazo que solucione dichas necesidades.
Tarea EVS 1.1: Estudio de la solicitud
Descripción general del sistema: el objetivo es desarrollar una plataforma para
la corrección automática de la Práctica Final de Estructuras Dinámicas (PFED) de
la asignatura de Fundamentos de Programación II. Esta práctica final se evaluará
en dos momentos distintos. En primer lugar se corregirá el desarrollo del trabajo
siguiendo el enunciado de la PFED entregado a los alumnos y después se realizará
un examen en el Centro de Cálculo de la Escuela Técnica Superior de Ingeniería
de Sevilla. En esta segunda evaluación se pedirán una serie de modificaciones
que los alumnos deben realizar satisfactoriamente en el tiempo establecido para
aprobar la asignatura.
13 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
Una vez realizadas las evaluaciones oportunas, se deberá realizar un control
sobre los trabajos realizados para regular un posible plagio.
Las principales funciones de este sistema son:
o Registro en el sistema por parte de los alumnos que realicen el trabajo.
o Ejecución de las pruebas propuestas por los profesores.
o Recepción de mensajes de error o de confirmación en función de los
resultados de la compilación y la ejecución de las pruebas.
o Corrección automática de los trabajos.
o Control de plagio.
Catálogo de objetivos del EVS: el objetivo del EVS es obtener información lo más
detallada posible del sistema que se va a desarrollar. Para ello, se obtendrá un
conjunto de funcionalidades mínimas para desarrollar una primera solución,
contando con las diferentes restricciones, como por ejemplo, técnicas y
económicas, entre otras.
Una descripción detallada de los objetivos se muestra en la tabla 1.
OBJETIVO DESCRIPCIÓN
Estudio de la situación actual
Se estudia el funcionamiento de los sistemas de información para conseguir la solución óptima, contando con el apoyo de los requisitos.
Definición de requisitos del sistema
Definimos requisito como una funcionalidad o un conjunto de ellas que se necesita, junto con su descripción de comportamiento y una prioridad.
Estudio de alternativas Se realiza después de haber estudiado el campo de desarrollo y se establecen un conjunto de todas las posibles soluciones que satisfagan las necesidades.
Valoración de alternativas Se debe valorar cada alternativa descrita y sus costes, beneficios y riesgos para poder realizar la comparativa.
Selección de la solución Se elige la solución que más se adapte a la las necesidades y, en caso contrario, se inicializa nuevamente el estudio de viabilidad.
Tabla 1. Descripción de objetivos EVS
Catálogo de requisitos: Una descripción detallada de los requisitos generales se
muestra en las tablas 2-6.
14 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
o Requisitos generales del sistema:
RG-01 Funcionamiento del sistema
Importancia Alta Prioridad Alta Descripción El sistema debe calificar la PFED. Tanto en la fase de
desarrollo del trabajo como la evaluación posterior.
Tabla 2. RG-01
RG-02 Corrección del trabajo
Importancia Alta Prioridad Alta Descripción El sistema debe corregir el trabajo de los alumnos. Para
ello el sistema debe integrar y utilizar la herramienta desarrollada por el departamento para este propósito.
Tabla 3. RG-02
RG-03 Corrección de la evaluación
Importancia Alta Prioridad Alta Descripción El sistema debe corregir el examen realizado por los
alumnos. El sistema debe comprobar que los apartados del examen son realizados correctamente y almacenar la nota correspondiente.
Tabla 4. RG-03
RG-04 Interfaz gráfica
Importancia Alta Prioridad Alta Descripción El sistema debe implementar una interfaz gráfica para
el alumno. De esta manera se desea conseguir una mayor aceptación del sistema por parte del alumnado.
Tabla 5. RG-04
RG-05 Control de plagio
Importancia Alta Prioridad Alta Descripción El sistema debe controlar e informar en caso de que se
detecte un plagio entre los distintos trabajos de los alumnos.
Tabla 6. RG-05
15 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
Tarea EVS 1.2: Identificación del alcance del sistema
Descripción general del sistema: el contexto del sistema abarca a las personas
involucradas en el la asignatura de FP2, tanto alumnos como profesores. Las
funcionalidades serán distintas para ambos.
Catálogo de requisitos: existe un requisito dependiente de otro sistema ya
implementado. Este requisito trata sobre la utilización de una base de datos
MongoDB para el modelo de datos. Una descripción detallada de estos requisitos
se encuentra en el apartado EVS 3.3.
Catálogo de usuarios: el sistema tendrá dos tipos de usuarios que interactúen
con él.
o Alumno: accederá al sistema a través de la interfaz de cliente y se le
permitirá introducirse en el sistema, compilar y ejecutar las distintas
pruebas disponibles todas las veces que considere oportuno.
o Profesor: obtendrá las valoraciones generadas a través del sistema y el
informe sobre el control de plagio realizado.
Tarea EVS 1.3: Especificación del alcance del sistema
Catálogo de objetivos del EVS: no se especifican nuevos requisitos.
Catálogo de usuarios: los usuarios no han variado desde el estudio anterior, en
la tarea EVS 1.2, por lo que siguen siendo los mismos que allí se citan y siguen
manteniendo las mismas funcionalidades.
Plan de trabajo: el proyecto debe estar completado antes de la evaluación
correspondiente de los alumnos, de modo que se estima que la distribución
temporal del trabajo sea la siguiente:
16 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
ACTIVIDAD EVS 2: ESTUDIO DE LA SITUACIÓN ACTUAL
El estudio de la situación actual estudia la solución ya existente del sistema corrector
pero que ha sido desarrollada en lenguaje C y realizada para la corrección del trabajo de
programación orientada a objetos de FP2.
Tarea EVS 2.1: Valoración del Estudio de la Situación Actual
En la actualidad, los alumnos que desean presentarse al examen de la asignatura de
Fundamentos de Programación deben desarrollar la Práctica Final de Estructuras
Dinámicas (PFED). Para comprobar si han realizado la práctica correctamente el
Departamento de Telemática de la Universidad de Sevilla ha desarrollado una
herramienta que dado el código fuente del trabajo del alumno y una serie de ficheros
de configuración, ejecuta una serie de pruebas. Este sistema se ejecuta de manera local
en una máquina y comprueba el buen comportamiento del código del alumno. En
particular, indica si existen errores en la salida estándar y genera un informe sobre la
gestión de memoria.
En caso de que la herramienta antes descrita indique que el trabajo se ha realizado
correctamente, el alumno envía su trabajo para ser evaluado. A continuación debe
presentarse a un examen práctico en el cual se le pedirán modificaciones al código de
su trabajo. Este examén se realiza in situ en un aula del Centro de Cálculo de la Escuela
Superior de Ingeniería de la Universidad de Sevilla. El examen consta de 4 apartados. En
el primero de ellos simplemente se pide ejecutar la misma herramienta que han debido
ejecutar los días previos al examen. En los otros 3 apartados el alumno debe modificar
su código para que genere un determinado fichero con la información requerida. En la
actualidad, para que el alumno pueda comprobar que ha realizado el apartado
correctamente se ofrecen las salidas que deben de dar los apartados y mediante el
17 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
comando diff [24] de Linux se comprueba que no exista ninguna diferencia entre el
fichero generado por el alumno y el aportado con el examen.
Una vez realizado el examen, el alumno envía su código con las modificaciones
requeridas y posteriormente el profesorado evalúa cada uno de los apartados de los
alumnos presentados.
Para automatizar ese proceso existe una solución desarrollada por Sergio Bellido
Sánchez, Ingeniero de Telecomunicación de la Universidad de Sevilla, el cual desarrolló
una aplicación cliente-servidor en lenguaje de programación C.
En esta solución los alumnos ejecutan el programa cliente, que se conecta con el
programa servidor, este recibe el código procedente del alumno, así como las órdenes
de compilación del código fuente y la ejecución de las pruebas.
Esta herramienta fue desarrollada para un trabajo concreto que trataba sobre el
desarrollo de una agenda usando el lenguaje de programación orientado a objetos Java
(Práctica Final Programación Orientada a Objetos). Los datos de los alumnos son
almacenados en una base de datos MongoDB. El diagrama de la figura 3 muestra la
secuencia de ejecución de este sistema:
Figura 3. Ejecución del sistema
En cuanto al control de plagio existen diferentes alternativas como ya expusimos en el
bloque 1. En nuestro caso nos decantaremos por utilizar el software “similarity tester
18 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
SIM” desarrollado por el profesor Dick Grune del departamento de Ciencias de
Computación de la Universidad de Amsterdam. Este programa devuelve el porcentaje
de similitud entre varios ficheros comparados ya sean ficheros de código fuente o texto
plano.
Tarea EVS 2.2: Identificación de los Usuarios Participantes en el Estudio de la Situación
Actual
En cuanto a los usuarios involucrados son los mismos que los descritos en el apartado
EVS 1.2
Tarea EVS 2.3: Descripción de los Sistemas de Información Existentes
Como se muestra en la figura 4 el sistema está formado por 3 bloques principales. En el
lado del cliente se encuentra el usuario. Este sólo debe tener su código fuente y la
interfaz del sistema para el alumno.
Ya no se ejecutan las pruebas de manera local si no que es el servidor remoto el que
recibe los ficheros con el código del alumno y es en esta máquina donde se ejecutan las
pruebas correspondientes.
A su vez el servidor principal se conecta con el servidor de la base de datos. El servidor
de base de datos utilizado es MongoDB. Este puede estar en la misma máquina que el
servidor o bien conectarse a ella remotamente.
Figura 4. Diagrama de bloques del sistema.
Tarea EVS 2.4: Realización del Diagnóstico de la Situación Actual
La implementación estudiada de la situación actual presenta algunas carencias. En
general obtenemos las siguientes conclusiones:
El sistema solo es aplicable al trabajo para el que fue desarrollado.
No es portable a cualquier sistema operativo debido al lenguaje de programación
utilizado.
Esta desarrollado para corregir solo trabajos escritos en lenguaje de
programación orientado a objetos.
Existe una herramienta ya desarrollada que realiza al menos en parte el control
de plagio que queremos desarrollar.
19 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
Disponemos de una arquitectura de información ya implantada.
ACTIVIDAD EVS 3: DEFINICIÓN DE REQUISITOS DEL SISTEMA
Tarea EVS 3.1: Identificación de las directrices técnicas y de gestión
A continuación se muestra el catálogo de normas que da una visión de las directrices
técnicas y de gestión. Aquí se recoge información sobre los estándares y procedimientos
que deben tenerse en cuenta a la hora de exponer una posible solución.
Políticas técnicas: en lo que respecta a la gestión del proyecto se puede decir
que se realizará un seguimiento periódico y se dará la aprobación final al
concluirlo.
La herramienta utilizada para la realización del modelado será MagicDraw UML.
La implementación se hará siguiendo el esquema de la programación orientada
a objetos. El lenguaje de programación utilizado será Java con el entorno de
desarrollo Eclipse. La documentación y planificación del proyecto se realizará a
través de la suite de Microsoft Office.
La arquitectura del sistema será centralizada utilizando uno o varios servidores.
Este servidor será accedido a través de Internet con un puerto TCP. La red de
acceso utilizada será la disponible en la Escuela Técnica Superior de Ingeniería.
Política de seguridad: solo deberán acceder al sistema de evaluación los
alumnos matriculados en la asignatura. Cada alumno accederá con un usuario
único (su UVUS) por el que será identificado.
Tarea EVS 3.2: Identificación de requisitos
Debido al modelo de desarrollo que se ha escogido, se deberán mantener a lo largo de
la duración del proyecto sesiones de trabajo con el profesor responsable de la
asignatura, donde este propondrá mejoras y mostrará los errores que ha detectado
hasta el momento. De momento no incluiremos más requisitos.
Tarea EVS 3.3: Catalogación de requisitos
Ya se han especificado los requisitos generales del sistema. En las tablas 7-19 se detallan
todos los demás requisitos que el sistema debe cumplir.
Requisitos Funcionales del Sistema
o Requisitos de Información del Sistema
RI-01 Datos Alumno
Dependencias Asociados a un alumno de la asignatura.
Generados automáticamente por el sistema.
Serán modificados en los casos de uso CS-04 y CS-05
20 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
Descripción El sistema deberá almacenar la información correspondiente a cada uno de los alumnos de la asignatura. En concreto los campos a almacenar serán:
UVUS del alumno
Nombre del alumno
Apellidos del alumno
Nota del trabajo
Nota de cada uno de los apartados del examen
Importancia Alta Comentarios La base de datos será de tipo no relacionas. En concreto
se usará MongoDB.
Tabla 7. RI-01
o Requisitos de conducta del sistema
RC-01 Servidor no disponible
Dependencias Descripción El sistema deberá alertar al usuario en caso de que no
se encuentre disponible el servidor. Importancia Alta Comentarios El mensaje se mostrará mediante la interfaz gráfica del
alumno.
Tabla 8. RC-01
RC-02 Base de datos no disponible
Dependencias Descripción El sistema deberá alertar al usuario en caso de que no
se encuentre disponible la base de datos. Importancia Alta Comentarios El mensaje se mostrará mediante la interfaz gráfica del
alumno.
Tabla 9. RC-02
RC-03 Autenticación incorrecta
Dependencias Relacionado con el caso de uso CS-07 Descripción El sistema deberá alertar al alumno en caso de se
introduzca un nombre de usuario no válido. Importancia Alta Comentarios El mensaje se mostrará mediante la interfaz gráfica del
alumno.
Tabla 10. RC-03
RC-04 Ejecución satisfactoria de la herramienta
Dependencias Relacionado con el caso de uso CS-04 y CS-08
21 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
Descripción El sistema deberá alertar al alumno si se han pasado las pruebas de la herramienta en el servidor satisfactoriamente. Se almacenará en la base de datos la información correspondiente.
Importancia Alta Comentarios El mensaje se mostrará mediante la interfaz gráfica del
alumno.
Tabla 11. RC-04
RC-05 Ejecución satisfactoria de apartado
Dependencias Relacionado con el caso de uso CS-05 y CS-08 Descripción El sistema deberá alertar al alumno si se ha pasado la
ejecución de un apartado del examen. Se almacenará en la base de datos la información correspondiente.
Importancia Alta Comentarios El mensaje se mostrará mediante la interfaz gráfica del
alumno.
Tabla 12. RC-05
RC-06 Ejecución fallida
Dependencias Relacionado con el caso de uso CS-04 y CS-05 Descripción El sistema deberá alertar al alumno en caso de que la
ejecución de la herramienta o de un apartado sea incorrecta.
Importancia Alta Comentarios El mensaje se mostrará mediante la interfaz gráfica del
alumno. Además, en caso de no pasar las pruebas de la herramienta, se generará un fichero con el informe del error.
Tabla 13. RC-06
Requisitos No Funcionales del Sistema
o Requisitos de Seguridad
RS-01 Control de acceso
Dependencias Relacionado con el caso de uso CS-01 Descripción Solo se debe permitir el acceso al sistema por parte del
personal autorizado. Solo los alumnos matriculados deben poder introducirse en el sistema y solo el profesorado acceder a las notas.
Importancia Media Comentarios Los alumnos accederás a través de la interfaz gráfica y los
profesores físicamente a través de la maquina servidor.
Tabla 14. RS-01
22 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
o Requisitos de Fiabilidad
RF-01 Concurrencia
Dependencias Descripción El sistema deberá permitir el uso concurrente del
mismo por parte de varios alumnos simultáneamente. Importancia Alta Comentarios
Tabla 15. RF-01
o Requisitos de Usabilidad
RU-01 Sencillez
Dependencias Descripción El sistema deberá ofrecer una interfaz gráfica para el
alumno, de manera que pueda acceder a todas sus funcionalidades con menos de 2 clics.
Importancia Media Comentarios
Tabla 16. RU-01
o Requisitos de Mantenibilidad
RM-01 Duración
Dependencias Descripción El sistema debe ser utilizable en futuras convocatorias y
para otras PFED en los próximos años. Importancia Alta Comentarios
Tabla 17. RM-01
o Requisitos de Portabilidad
RP-01 Portabilidad
Dependencias Descripción El sistema debe funcionar principalmente en el CDC.
Aunque debe ser portable a otros sistemas operativos. Importancia Media Comentarios
Tabla 18. RP-01
Otros Requisitos No Funcionales
RNF-01 Funcionamiento remoto
Dependencias Descripción El sistema deberá estar descentralizado, el equipo con
el software del servidor y de la base de datos será el equipo del despacho del profesor correspondiente. Los
23 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
alumnos ejecutarán la interfaz de cliente en sus propios ordenadores o en el CDC.
Importancia Alta Comentarios
Tabla 19. RNF-01
ACTIVIDAD EVS 4: ESTUDIO DE ALTERNATIVAS DE SOLUCIÓN
Tarea EVS 4.1: Preselección de alternativas de solución
Descomposición inicial del sistema en subsistemas. Tras la obtención de
requisitos de la actividad EVS 3.3 vemos que el sistema principal puede dividirse
en distintos subsistemas. Con esta división buscamos que cada uno de los
subsistemas tenga la menor dependencia del resto de subsistemas. La división
realizada puede verse en la figura 5. En esta figura se definen cada uno de los
componentes que deberán existir en nuestro sistema y los actores relacionados
con las mismas. Una especificación más detallada de los actores definidos puede
verse en la tarea ASI 2.1.
Figura 5. Descomposición en subsistemas
24 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Estudio de la viabilidad del sistema
(EVS)
Alternativas de solución a estudiar. Para cumplir con la especificación de
requisitos e implementar cada uno de los sistemas disponemos de dos
alternativas. O reutilizar el software ya desarrollado y adaptarlo a las
necesidades de nuestro sistema, o por el contrario, desarrollar nuestro propio
software desde cero.
Tarea EVS 4.2: Descripción de las alternativas de solución
Alternativas de solución a implementar:
o Cobertura de los requisitos: en el caso de utilizar el software existente
no se asegura el requisito de portabilidad y aplicación a un proyecto
desarrollado con programación estructurada. Cabe la posibilidad de
tener que abandonar el proyecto al no poder este software cumplir los
requisitos especificados. Un desarrollo desde cero asegura cumplir todos
los requisitos.
o Entorno Tecnológico y Comunicaciones: en ambos casos se desarrollará
el sistema de corrección automática en un entorno Linux. En caso de
utilizar el software ya desarrollado se utilizará el lenguaje de
programación C. Si la opción elegida es el desarrollo total del sistema se
utilizará el lenguaje de programación Java por motivos de sencillez y
portabilidad.
La base de datos utilizada será MongoDB en cualquiera de los casos, por
los motivos especificados en el bloque 1.
Para el establecimiento de las comunicaciones será necesario que tanto
el equipo del alumno como el del profesor estén interconectados ya sea
mediante una red de área local o Internet. El ancho de banda de la
conexión no necesita ser superior a 1 Mbps ya que el tráfico cursado no
superará 1 Mb por alumno.
o Estrategia de Implantación Global del Sistema: se implementará el
sistema para que los alumnos puedan realizar la comprobación de su
trabajo de manera telemática. Ya sea desde el Centro de Cálculo o desde
un equipo personal.
ACTIVIDAD EVS 5: VALORACIÓN DE LAS ALTERNATIVAS Tarea EVS 5.1: Estudio de la inversión
Impacto en la Organización de Alternativas: el principal objetivo de este sistema
es simplificar la gestión de la evaluación de la PFED existente. En ambas
alternativas el resultado final de evaluación debe ser el mismo, sin embargo, en
caso de usar el lenguaje de programación Java se simplifica su utilización por
parte del alumno ya que existen librerías para crear una interfaz gráfica de
manera sencilla.
Coste / beneficio de Alternativas: entre las dos opciones disponibles, si
reutilizamos el código ya desarrollado, representaría un coste menor en cuanto
25 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
al número de horas de desarrollo. Sin embargo, al comenzar el proyecto desde
cero conseguimos cumplir los requisitos de portabilidad, además de adaptar la
solución a la corrección del trabajo basado en lenguaje estructurado.
Este proyecto se trata de un Trabajo Final de Grado por lo que no existe un coste
real de implementación. Para ello se utilizará tanto software como hardware
disponible para los alumnos de la Universidad de Sevilla.
Tarea EVS 5.2: Estudio de los Riesgos
Debido al carácter académico del trabajo existen riesgos derivados de la inexperiencia
en el desarrollo de este tipo de proyectos.
Para evitar que el proyecto fracase y no se encuentre disponible para la fecha límite se
realizaran revisiones en las que se analizará el progreso realizado y los problemas
encontrados. Esta fecha límite está marcada en la planificación como la fecha de
evaluación real de la PFED.
Tarea EVS 5.3: Planificación de Alternativas
La planificación de la solución fue analizada en el apartado EVS 1.3. En ambas
alternativas posibles, la planificación sería similar, solo cambiaría el modo de desarrollo.
ACTIVIDAD EVS 6: SELECCIÓN DE LA SOLUCIÓN
En nuestro caso no existe un Comité de Dirección que evalúe las posibles alternativas de
desarrollo. De modo que, una vez estudiadas las distintas opciones disponibles,
decidimos:
Diseñar un software desde cero para el sistema corrector usando el lenguaje de
programación Java. Con esto nos aseguramos la portabilidad, la compatibilidad
con Linux y los equipos de la Universidad de Sevilla, así como la posibilidad de
desarrollo de la interfaz gráfica. En cualquier caso reutilizaremos la arquitectura
de información del software ya desarrollado.
En cuanto al sistema de control de plagio optamos por implementar una solución
que utilizando el software SIM genere un informe con la información sobre el
posible plagio entre los trabajos de los alumnos. El software SIM solo es
compatible con el SO Windows, pero esto no es un aspecto crítico ya que se
utilizará de manera posterior al examen y solo es necesario copiar el trabajo de
los alumnos a un equipo que ejecute este SO. Aun así consideramos necesario
desarrollar otra herramienta que realice de manera automática esta tarea.
Análisis del Sistema de Información (ASI) El objetivo de este proceso [29] es obtener de forma detallada la especificación del
sistema de información que satisfaga las necesidades de los usuarios y sirva de guía para
el diseño del sistema.
26 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
El esquema de las actividades a realizar en este proceso se muestra en la figura 6.
Figura 6. Proceso ASI
Nuestro sistema será desarrollado siguiendo el modelo orientado a objetos de modo
que no se incluirán en esta memoria las actividades ASI 6 y 7.
ACTIVIDAD ASI 1: DEFINICIÓN DEL SISTEMA Tarea ASI 1.1: Determinación del Alcance del Sistema
Catálogo de requisitos: es el mismo obtenido de la actividad EVS.
Glosario:
o Alumno, usuario final del sistema.
o Profesor, usuario que extrae los datos finales obtenidos.
o Servidor, máquina que gestiona las peticiones de los alumnos.
o MongoDB, base de datos utilizada basada en NoSQL (Not only SQL).
o Colección, unidad de almacenamiento de información en MongoDB
(equivalente a una relación en lenguaje SQL).
o Documento, elemento de una colección de MongoDB (análogo a una
tupla en lenguaje SQL).
o Herramienta, software desarrollado por el Departamento de Telemática
para la ejecución de pruebas del trabajo del alumno.
Tarea ASI 1.2: Identificación del Entorno Tecnológico
Catálogo de requisitos: no se han obtenido nuevos requisitos desde los
detallados en el EVS.
27 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Descripción general del entorno tecnológico del sistema: siguiendo con lo
expuesto en el apartado EVS 4.2, consideramos que el entorno tecnológico debe
cumplir:
o En el equipo del alumno:
Sistema operativo Linux (Ubuntu).
Conexión de red (recomendable al menos 1 Mbps).
Java Runtime Environment.
Versión del alumno del proyecto desarrollado. Ya sea la versión
para la entrega de la PFED o para el examen.
Código fuente del trabajo del alumno.
o En el equipo servidor:
Sistemas operativos Linux (fase de evaluación) y Windows (fase
de control de plagio).
Conexión de red (recomendable al menos 10 Mbps).
Java Runtime Environment (al menos versión 1.7).
Base de datos MongoDB.
Versión del servidor del proyecto desarrollado.
Software SIM.
Tarea ASI 1.3: Especificación de Estándares y Normas
Actualizamos lo comentado en la tarea EVS 3.1. Para el desarrollo de nuestro sistema
seguiremos la siguiente metodología de programación:
Separación por clases: Se utilizará un modelo de clases en el que cada una de
ellas tendrá solo los atributos que la identifiquen y los métodos necesarios para
su correcto funcionamiento.
Nombres de clases: Se utilizarán nombres descriptivos. Utilizaremos el estándar
Pascal case [25].
Nombres de variables y métodos: Mismo caso que el anterior. Utilizaremos el
estándar Camel case.
Diseño de la interfaz: Se minimizará el uso de texto. Con una interfaz clara y
simple de usar por parte del alumno.
Tarea ASI 1.4: Identificación de los Usuarios Participantes y Finales
Catálogo de usuarios: los usuarios implicados en la aplicación siguen siendo los
mismos que los que se describieron en la tarea EVS 1.2. Los profesores de la
asignatura de FP2 serán los encargados de la especificación de requisitos y de la
validación del sistema. Este proyecto implica a un solo desarrollador que se
encargará de la programación del sistema y su puesta en marcha.
Plan de trabajo: el plan de trabajo no ha variado desde que se describió en la
tarea EVS 1.3.
28 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
ACTIVIDAD ASI 2: ESTABLECIMIENTO DE REQUISITOS Tarea ASI 2.1: Obtención de Requisitos
Catálogo de requisitos: es el mismo que el de la tarea ASI 1.1.
Modelo de Casos de Uso: antes de especificar el modelado de los casos de uso
es necesario detallar cuáles serán los actores que intervendrán en nuestro
sistema. Estos actores no tienen por qué ser entidades físicas pero si son
importantes para la interacción con el sistema.
Act-01 Alumno
Descripción Usuario que accederá al sistema a través de la interfaz de cliente y se le permitirá introducirse en el sistema además de ejecutar las pruebas disponibles todas las veces que considere oportuno.
Tabla 20. Act-01
Act-02 Profesor
Descripción Encargado de mantenimiento del sistema. Obtendrá las valoraciones generadas a través del sistema.
Tabla 21. Act-02
Act-03 Base de datos
Descripción El actor Base de Datos es el sistema que permite el almacenamiento persistente de la información de los alumnos y sus calificaciones.
Tabla 22. Act-03
Act-04 Servidor
Descripción El actor Servidor es el sistema que permite la ejecución de las peticiones realizadas por los alumnos. Es el encargado de gestionar las notas de los alumnos y de generar el informe a los profesores.
Tabla 23. Act-04
Una vez definidos los actores de nuestro sistema pasamos a ver en las figuras 7-9
cuál será el Modelo de Casos de Uso que vamos a implementar.
29 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Figura 7. Gestión de la corrección de la PFED
Figura 8. Gestión de la corrección del examen
30 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Figura 9. Detalle de Casos de uso.
Tarea ASI 2.2: Especificación de Casos de Uso
A continuación vamos a especificar cada uno de los casos de uso detallados en los
modelos anteriores.
CS-01 Registro
Dependencias Invoca a los casos de uso comprobar nombre de usuario y almacenar datos.
Los actores implicados en este caso de uso son Alumno y Base de Datos
Descripción En el caso de que sea un usuario válido, el sistema deberá introducir (si no se encuentra ya) en el registro.
Prioridad Alta
Tabla 24. CS-01
CS-02 Enviar trabajo
Dependencias Invoca al caso de uso Almacenar ficheros.
El actor implicado en este caso de uso es Alumno.
31 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Descripción Una vez validado el registro el Alumno envía en un fichero comprimido su trabajo. Si el resultado es satisfactorio se muestra un mensaje de confirmación. En caso contrario se indicará un fallo de conexión con el servidor.
Prioridad Alta
Tabla 25. CS-02
CS-03 Enviar examen
Dependencias Invoca a los casos de uso Almacenar ficheros y Comprobar ficheros.
El actor implicado en este caso de uso es Alumno.
Descripción Una vez validado el registro, el Alumno envía en un fichero comprimido su examen. Se comprueba que no se ha modificado ningún fichero crítico. Si el resultado es satisfactorio se muestra un mensaje de confirmación. En caso contrario se indicará si el fallo ha sido de conexión o de integridad de los ficheros.
Prioridad Alta
Tabla 26. CS-03
CS-04 Ejecutar herramienta
Dependencias No invoca a ningún otro caso de uso.
Los actores implicados en este caso de uso son Alumno y Servidor.
Descripción Una vez se ha enviado y descomprimido el fichero con el trabajo del alumno, a petición del mismo, se procede a la ejecución de la herramienta con las pruebas asignadas en el servidor. Si el resultado es satisfactorio se muestra un mensaje de confirmación. En caso contrario generará un informe con el resultado obtenido y se enviará de vuelta al Alumno.
Prioridad Alta
Tabla 27. CS-04
CS-05 Corregir apartado
Dependencias No invoca a ningún otro caso de uso.
Los actores implicados en este caso de uso son Alumno y Servidor.
Descripción Una vez se ha enviado y descomprimido el fichero con el examen del alumno, se procede a la comprobación del correcto funcionamiento de cada uno de los apartados del examen en el servidor. Si el resultado es satisfactorio se muestra un mensaje de confirmación.
32 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
En caso contrario generará un informe con el resultado obtenido y se enviará de vuelta al Alumno.
Prioridad Alta
Tabla 28. CS-051
CS-06 Obtener notas
Dependencias Invoca a los casos de uso Consultar datos e Imprimir fichero de notas.
El actor implicado en este caso de uso es Profesor.
Descripción Cuando el Profesor considere oportuno el fin del proceso de obtención de los resultados de los alumnos cerrará el sistema generando los ficheros con la nota correspondiente de los alumnos.
Prioridad Alta
Tabla 29. CS-06
CS-07 Comprobar nombre de usuario
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es el Servidor.
Descripción Una vez el sistema recibe un nombre de usuario por parte del Alumno, el servidor comprueba que es un UVUS válido y se encuentra en la lista. En caso contrario no permite el acceso al sistema y envía un mensaje de error al Alumno.
Prioridad Media
Tabla 30. CS-07
CS-08 Almacenar datos
Dependencias No invoca a ningún otro caso de uso.
Los actores implicados en este caso de uso son Alumno y Base de datos.
Descripción Si es la primera vez que el usuario entra en el sistema se almacenan sus datos en la base de datos. Al ejecutar la herramienta o algún apartado del examen se almacena la nota correspondiente. Después se envía confirmación al Alumno.
Prioridad Media
Tabla 31. CS-08
CS-09 Almacenar ficheros
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es Servidor.
33 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Descripción Una vez que el usuario ha sido validado se almacenan los ficheros de su trabajo en el sistema de ficheros del servidor.
Prioridad Alta
Tabla 32. CS-09
CS-10 Comprobar ficheros
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es Servidor.
Descripción Cuando se envían los ficheros del examen se comprueba que los ficheros pertenecientes al enunciado no han sido modificados para realizar comportamientos no deseados.
Prioridad Media
Tabla 33. CS-10
CS-11 Consultar datos
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es Profesor, Servidor y Base de datos.
Descripción Cuando un profesor quiere obtener las notas de los alumnos, el servidor envía una petición a la base de datos para que liste la información necesaria.
Prioridad Alta
Tabla 34. CS-11
CS-12 Imprimir fichero de notas
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es Servidor y Base de datos.
Descripción El servidor recibe la información correspondiente a las notas de la base de datos y las imprime en un fichero para su visualización.
Prioridad Media
Tabla 35. CS-12
CS-13 Generar informe de plagio
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es Servidor y Base de datos.
Descripción El Servidor utiliza el software SIM para buscar similitudes entre los ficheros de código de los alumnos e imprime en un fichero la información obtenida.
Prioridad Alta
Tabla 36. CS-13
34 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
CS-14 Obtener informe de plagio
Dependencias No invoca a ningún otro caso de uso.
El actor implicado en este caso de uso es Servidor y Base de datos.
Descripción El Profesor envía la petición al servidor para que realice el control de plagio. Recibe un fichero con el informe realizado.
Prioridad Alta
Tabla 37. CS-14
Tarea ASI 2.3: Análisis de Requisitos
No se han detectado inconsistencias ni ambigüedades ni escasez de información en la
especificación de los requisitos y de los casos de uso.
Tarea ASI 2.4: Validación de Requisitos
Todos los requisitos especificados y los casos de uso se ha confirmado que son válidos y
consistentes.
ACTIVIDAD ASI 3: IDENTIFICACIÓN DE SUBSISTEMAS DE ANÁLISIS
Tarea ASI 3.1: Determinación de Subsistemas de Análisis
Descripción de subsistemas de análisis: la descomposición en subsistemas es la
que se detalla en la tarea EVS 4.1.
Descripción de interfaces entre subsistemas: la dependencia existente entre los
distintos sistemas se muestra en la figura 10. La funcionalidad asociada a cada
subsistema es la misma que en la especificación de los casos de uso. En la tabla
38 se detallan los requisitos y los casos de uso asociados a cada subsistema.
Figura 10. Dependencia entre subsistemas
35 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Subsistema Requisitos Casos de uso
Gestión del servidor
Funcionamiento del sistema
Control de acceso
Concurrencia
Registro
Almacenar datos
Almacenar ficheros
Comprobar ficheros
Consultar datos
Imprimir fichero de notas
Obtener informe de plagio
Gestión de la corrección del
examen
Corrección de la evaluación
Interfaz gráfica
Enviar examen
Corregir apartado
Gestión de la corrección de la
PFED
Corrección del trabajo
Interfaz gráfica
Enviar trabajo
Ejecutar herramienta
Gestión de notas Datos Alumno Obtener notas
Almacenar datos
Gestión de plagio Control de plagio Generar informe de
plagio
Tabla 38. Asociación de subsistemas
Tarea ASI 3.2: Integración de Subsistemas de Análisis
Descripción de subsistemas de análisis: los subsistemas de análisis serán los
mismos que los especificados anteriormente:
o Gestión del servidor. Subsistema encargado de asegurar el correcto
funcionamiento principal del sistema. Recibirá las peticiones de los
alumnos, ejecutará las pruebas necesarias y facilitará los ficheros de nota
y de control de plagio.
o Gestión de la corrección del examen. Se encargará de la gestión del
examen del alumno. Enviará el examen al servidor y las peticiones para
corregir los distintos apartados. Generará las respuestas pertinentes.
o Gestión de la corrección de la PFED. Se encargará de la corrección de la
Práctica Final de Estructuras Dinámicas. Recibirá el trabajo del alumno y
ejecutara la herramienta de corrección. Generará las respuestas
pertinentes.
o Gestión de notas. Será el subsistema encargado de comunicarse con la
base de datos. Ya sea establecer las notas de un alumno o recibirlas.
o Gestión de plagio. Subsistema encargado del análisis del código
entregado por los alumnos con el objetivo de detectar posibles plagios
entre los trabajos entregados y generar un informe con dicha
información.
36 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
ACTIVIDAD ASI 4: ANÁLISIS DE LOS CASOS DE USO
Tarea ASI 4.1: Identificación de Clases Asociadas a un Caso de Uso
Se han identificado los candidatos a ser clases partiendo de los casos de uso. Para cubrir
todas las funcionalidades y requisitos asociados a los distintos casos de uso se han
definido las clases expuestas en el apartado ASI 5.
Tarea ASI 4.2: Descripción de la Interacción de Objetos
Análisis de la realización de los casos de uso: en el diagrama de secuencia de la
figura 12 podemos observar la interacción entre el Alumno y el sistema. Por otro
lado en la figura 11 podemos ver la interacción con el Profesor.
Figura 11. Interacción Profesor-Sistema
37 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Figura 12. Interacción Alumno-Sistema
ACTIVIDAD ASI 5: ANÁLISIS DE CLASES
Tarea ASI 5.1: Identificación de Responsabilidades y Atributos
Cómo ya conocemos las funcionalidades del sistema y las operaciones que se deben
realizar, podemos realizar el diagrama de clases de la figura 13. También identificamos
los atributos necesarios para cada una de las entidades especificadas.
En este diagrama de clases existen 2 grandes bloques. Clases implementadas para la
interfaz del alumno y clases implementadas para el servidor. La parte correspondiente
al alumno comienza con la clase PrincipalAlumno, qué es la que contiene el método
main(). En él se crean un objeto Alumno con los datos del alumno que utiliza la
herramienta, un objeto Comunicación con los datos del servidor y un objeto Ventana
para mostrar la interfaz gráfica.
38 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Figura 13. Diagrama de clases del sistema
La clase Alumno contiene los datos básicos de un alumno: su UVUS y el fichero que
contiene su trabajo. Se implementan métodos get() para obtener estos parámetros.
La clase Fichero se trata de un envoltorio para la clase File de Java, esta clase debe
crearse a partir de la ruta en la que se encuentra el fichero de trabajo y además debe
almacenar la matriz de bytes del fichero y su tamaño para poder realizar las operaciones
de envío y transmisión de ficheros.
La clase ventana, como ya hemos dicho, es la que se encargará de mostrar la interfaz
gráfica. Contiene los textos y botones que se le mostrarán al alumno además de las
funciones asignadas a esos botones. También mostrará una animación de buffering
39 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
mientras que se procesan las peticiones y una imagen de un tick de confirmación cuando
el resultado de una operación sea satisfactorio.
Se implementa la clase Hilo para no bloquear el sistema con las peticiones realizadas.
Dependiendo del botón pulsado se le pasará al constructor de la clase un valor distinto
para realizar una tarea determinada.
La clase comunicación se encargará de gestionar la conexión entre el alumno y el
servidor. Se crea con la IP del servidor e implementa métodos para establecer y cerrar
la conexión con el cliente, además de enviar y recibir mensajes (de distintos tipos) y
ficheros.
El resto de las clases son implementadas por el servidor. La clase PrincipalServidor
implementa el método main(). Establecerá la conexión con la base de datos y cada vez
que reciba una petición iniciará un objeto Comunicación y creará un Hilo que la gestione.
La clase DataBase se encargará de realizar todas las operaciones correspondientes a la
gestión de la base de datos MongoDB que utilizaremos. Creará la lista de alumnos,
comprobará si los alumnos que se conectan pertenecen a la lista, borrará los datos si
queremos limpiar la base de datos y publicará y generará las notas correspondientes.
Finalmente la clase AlumnoServidor es la que se encarga de realizar todas las
operaciones de corrección y ejecución de las pruebas de los alumnos. Dependiendo de
la petición recibida por el alumno ejecutará la herramienta de pruebas al trabajo o
corregirá un apartado determinado. Además deberá comprobar que no se han
modificado ficheros críticos para la correcta corrección del examen.
Tarea ASI 5.2: Identificación de Asociaciones y Agregaciones
Como vemos en la figura 13 existen distintas asociaciones entre las clases definidas. La
clase PrincipalAlumno usa un objeto Alumno, un objeto Comunicación y un objeto
Ventana. Esta a su vez usa este objeto Comunicación para realizar las peticiones al
servidor, la clase Hilo para realizar operaciones en paralelo y la clase temporizador para
evitar bucles infinitos. La clase Alumno contiene un objeto Fichero con la información
del fichero con el trabajo.
En el lado del servidor la clase PrincipalServidor también usa un objeto Comunicación
para recibir las peticiones y un objeto DataBase para la conexión con la base de datos.
Para cada petición se crea un Hilo que utiliza una clase AlumnoServidor para realizar las
operaciones requeridas y la referencia al objeto DataBase que antes comentamos para
almacenar los resultados.
Tarea ASI 5.3: Identificación de Generalizaciones
Las clases HiloAlumno y HiloServidor heredan de la clase Hilo (Thread de Java) pero
ambas deben implementar procedimientos diferentes.
40 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
ACTIVIDAD ASI 8: DEFINICIÓN DE INTERFACES DE USUARIO
Tarea ASI 8.1: Especificación de Principios Generales de la Interfaz
Especificamos los principios generales de la interfaz tanto para la interfaz gráfica del
alumno como para la interfaz impresa del profesor.
En cuanto a la interfaz gráfica:
Debe ser lo más intuitiva y fácil de utilizar para los alumnos como sea posible.
La interacción con los distintos apartados debe ser sencilla y abstraer al usuario
final de la complejidad del sistema.
Los mensajes de confirmación y error deben ser mostrados en un cuadro de
texto en la interfaz.
En caso de producirse un error con el código del alumno se debe imprimir un
informe con la información del error generado en el servidor.
En cuanto a los informes generados:
Deben contener toda la información relevante sobre la evaluación de los
alumnos.
En caso de tratarse del informe con las notas finales debe estructurarse con una
tabla en la que se muestren tanto los datos personales del alumno como la nota
obtenida en cada apartado.
En caso de tratarse del informe de plagio se estructurará indicando la
identificación del alumno analizado, el porcentaje de posible plagio de sus
ficheros y la identificación del alumno plagiado.
Tarea ASI 8.2: Identificación de Perfiles y Diálogos
En cuanto al catálogo de perfiles de usuario podemos identificar dos perfiles bien
diferenciados:
Alumno: Posee la interfaz gráfica de usuario. No tiene conocimientos técnicos
sobre el sistema. Simplemente debe ejecutar el programa final y seguir los pasos
que se le indiquen. Interactuará con el sistema a través de los botones y la
ventana de diálogo proporcionada.
Profesor: Es el encargado del mantenimiento del sistema y de extraer los datos
del servidor. Debe poseer conocimientos básicos del funcionamiento del
sistema. Debe poner en marcha el servidor, detenerlo y obtener las notas y el
informe de plagio.
Tarea ASI 8.3: Especificación de Formatos Individuales de la Interfaz de Pantalla
Formatos Individuales de Interfaz de Pantalla: la pantalla principal debe estar
compuesta por una etiqueta que muestre una indicación sobre la actividad que
se está llevando a cabo. Un cuadro de texto con información relevante sobre la
ejecución y una serie de botones con las acciones posibles.
Catálogo de Controles y Elementos de Diseño de Interfaz de Pantalla: para
interactuar con el programa se utilizarán los botones antes descritos.
41 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Tarea ASI 8.4: Especificación del Comportamiento Dinámico de la Interfaz
La interfaz mostrará en cada momento las opciones posibles para el usuario y en caso
de que se ejecute alguna opción, el mensaje de confirmación o error correspondiente.
Tarea ASI 8.5: Especificación de Formatos de Impresión
Como ya hemos indicado los formatos de impresión seguirán la estructura marcada en
el apartado ASI 8.1. En la tabla 2 podemos ver un ejemplo del formato que se podría
seguir con la información necesaria relevante a las notas del alumno y en la tabla 3 de
la información de plagio.
Apellidos Nombre UVUS PFED Examen Aptdo 1
Examen Aptdo 2
Examen Aptdo 3
Martín Garcia
Juan juamargar 10 10 0 10
Tabla 2. Ejemplo de notas
Alumno analizado Fichero analizado Porcentaje plagiado
Alumno plagiado
juanmargar codigo.c 70 % marfertor
Tabla 3. Ejemplo de información de plagio
ACTIVIDAD ASI 9: ANÁLISIS DE CONSISTENCIA Y ESPECIFICACIÓN DE
REQUISITOS
Tarea ASI 9.1: Verificación de modelos
Los modelos especificados en la tarea ASI 1.3 se han verificado satisfactoriamente.
Aunque puedan existir modificaciones o mejoras según algunos criterios, se ha buscado
encontrar una solución de compromiso entre eficiencia y sencillez en el desarrollo.
Tarea ASI 9.2: Consistencia entre modelos
Siguiendo la especificación de MÉTRICA Versión 3 [29] analizamos los siguientes
aspectos para asegurar la consistencia:
Modelo de clases / Diagramas dinámicos:
o Cada mensaje entre objetos se corresponde con una operación de una
clase y que todos los mensajes se envían a las clases correctas.
o La clase que recibe un mensaje con petición de datos tiene capacidad
para proporcionar esos datos.
o Cada objeto del diagrama de interacción de objetos tiene una
correspondencia en el modelo de clases.
Modelo de clases / Interfaz de usuario
o Cada clase que requiera una clase de interfaz de usuario, debe tener
asociación con ella en el modelo de clases.
o Todas las clases, atributos y operaciones identificados en la interfaz de
usuario, deben tener su correspondencia con algún atributo, operación
o clase en el modelo de clases.
42 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Análisis del Sistema de Información
(ASI)
Analizados estos puntos podemos asegurar que nuestro sistema es consistente.
ACTIVIDAD ASI 10: ESPECIFICACIÓN DEL PLAN DE PRUEBAS
Tarea ASI 10.1: Definición del Alcance de las Pruebas
Los distintos niveles de pruebas que se van a realizar al sistema durante su desarrollo
son los que se citan a continuación:
Pruebas unitarias, de cada una de las funciones de las clases del sistema. Se
realizarán durante las primeras fases de programación del sistema. Deben
realizar correctamente su funcionalidad y devolver los valores esperados para
ser validadas.
Pruebas de integración, entre las distintas funciones. Se realizarán junto con las
pruebas unitarias. Para ser validadas las funciones de cada una de las clases
deben interoperar entre sí de manera satisfactoria.
Pruebas del sistema, una vez desarrolladas todas las clases del sistema se debe
probar en un entorno local el correcto funcionamiento total del sistema con
datos reales.
Pruebas de implantación, una vez superadas las pruebas del sistema de manera
local debe probarse en la localización real. Para ser verificadas el sistema debe
presentar el mismo resultado que en el entorno local.
Pruebas de aceptación. Finalmente será el profesorado el que valide el sistema
en su totalidad.
Tarea ASI 10.2: Definición de Requisitos del Entorno de Pruebas
Para la realización de las pruebas será necesario:
Un equipo para realizar las pruebas de manera local.
Acceso a un equipo de un despacho del departamento de telemática para
instalar el lado del servidor del sistema y un equipo del Centro de Cálculo para
las pruebas en red.
El software descrito en el apartado ASI 1.2.
La herramienta desarrollada para la ejecución de pruebas de la PFED para el
curso 2013-2014.
Un ejemplo de PFED desarrollada.
Tarea ASI 10.3: Definición de las Pruebas de Aceptación del Sistema
Para la aceptación del sistema es necesario:
Que un alumno pueda entrar en el sistema, entregar su trabajo, ejecutar las
pruebas oportunas y se genere su nota de forma correcta.
Que en caso de error tanto del sistema como del código del alumno se generen
los mensajes necesarios para su corrección.
Asegurar la disponibilidad del sistema ante peticiones simultáneas.
Almacenar y extraer correctamente los trabajos y notas de los alumnos, así como
el informe sobre la información de plagio.
43 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Diseño del Sistema de Información (DSI) El principal objetivo de este proceso [30] es la definición de la arquitectura del sistema
y del entorno tecnológico en el que se implementara. También se expone una
especificación detallada de los componentes del sistema de información.
Como podemos ver en la figura 14 las actividades de este proceso se dividen en dos
grandes bloques. El primer bloque contiene una serie de actividades en paralelo con el
objetivo de obtener en detalle el sistema de información. En el segundo bloque este
diseño se detalla con la información de especificación de construcción, carga inicial de
datos, especificación del plan de pruebas y los requisitos de implantación.
Figura 14. Estructura DSI
ACTIVIDAD DSI 1: DEFINICIÓN DE LA ARQUITECTURA DEL SISTEMA
Tarea DSI 1.1: Definición de Niveles de Arquitectura
El diseño de la arquitectura del sistema es el detallado en el apartado ASI 1.2. En esta
arquitectura tenemos dos nodos principalmente:
Nodo servidor. En este nodo se gestionarán todos los datos, se imprimirán los
ficheros obtenidos y se monitorizará el tráfico en caso de que sea necesario.
Nodo cliente. Este es el nodo perteneciente al alumno. Existirán tantos nodos
de este tipo como alumnos que se presenten a la asignatura.
La comunicación entre nodos se realizará bidireccionalmente mediante sockets. Estos
sockets implementarán la pila TCP/IP. La comunicación se realizará a través de paso de
mensajes simples y transferencia de ficheros.
44 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Tarea DSI 1.2: Identificación de Requisitos de Diseño y Construcción
Los requisitos a seguir son los siguientes:
El proyecto debe seguir la metodología MÉTRICA Versión 3.
El sistema debe llevarse a cabo mediante el lenguaje de programación Java.
La arquitectura debe ser distribuida (cliente-servidor).
Deben almacenarse los datos en una base de datos de tipo NoSQL MongoDB.
Tarea DSI 1.3: Especificación de Excepciones
Se han definido las siguientes excepciones:
Tipo de excepción Error al conectar con el servidor
Condiciones previas El servidor no está disponible.
Nodo afectado Cliente
Respuesta Error. No se ha podido conectar con el servidor.
Tipo de excepción Error al conectar con la base de datos
Condiciones previas La base de datos no está disponible.
Nodo afectado Servidor, cliente
Respuesta Error. No se ha podido conectar con la base de datos.
Tipo de excepción Error en la transferencia de ficheros
Condiciones previas Problemas con el sistema de ficheros o la conexión.
Nodo afectado Servidor, cliente
Respuesta Error. No se ha podido realizar la conexión satisfactoriamente.
Tipo de excepción Fichero no encontrado
Condiciones previas No existe el fichero con el trabajo del alumno.
Nodo afectado Cliente
Respuesta Error. Fichero no encontrado. Asegúrese de que el fichero comprimido con su trabajo se encuentra disponible.
Tipo de excepción Fichero crítico modificado
Condiciones previas El alumno ha modificado algún fichero del enunciado del examen.
Nodo afectado Servidor, cliente
Respuesta Error. Se ha modificado un fichero del enunciado. Asegúrese de que el contenido de estos ficheros permanece inalterado.
Tipo de excepción Usuario no válido
Condiciones previas El alumno se identifica con un UVUS que no está en la lista.
Nodo afectado Servidor, cliente
45 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Respuesta Error. Ha introducido un nombre de usuario no válido.
Tipo de excepción Error de compilación
Condiciones previas El código del alumno no es sintácticamente correcto y no se puede compilar.
Nodo afectado Servidor, cliente
Respuesta Error. Error de compilación en el código fuente de su trabajo.
Tipo de excepción Error de ejecución
Condiciones previas El código del alumno no realiza correctamente lo requerido.
Nodo afectado Servidor, cliente
Respuesta Error. Error de ejecución en el código fuente de su trabajo.
Tipo de excepción Error de memoria
Condiciones previas El código del alumno no gestiona correctamente el uso de memoria dinámica.
Nodo afectado Servidor, cliente
Respuesta Error. Error en la gestión de memoria dinámica de su trabajo.
Tarea DSI 1.4: Especificación de Estándares y Normas de Diseño y Construcción
El catálogo de normas no se ve modificado desde la versión anterior en ASI 1.3.
Tarea DSI 1.5: Identificación de Subsistemas de Diseño
La división e identificación de subsistemas realizadas en el apartado ASI 3 coinciden con
los subsistemas de Diseño. Esta división se completa al añadirle el subsistema de soporte
de la comunicación entre el nodo servidor y el cliente.
Tarea DSI 1.6: Especificación del Entorno Tecnológico
Hardware: los equipos deben tener, al menos una tarjeta de red para establecer
la conexión vía Internet. Además, el servidor debe tener una capacidad de
almacenamiento y procesamiento suficiente para recibir y gestionar los ficheros
y peticiones del cliente. El cliente debe disponer de un equipo con una pantalla,
ratón y un teclado para poder utilizar el sistema.
Software: es el mismo que el comentado en la tarea ASI 1.2
Comunicaciones: los requisitos de comunicación también se encuentran
especificados en la tarea ASI 1.2. La infraestructura de comunicación de la
Escuela Técnica Superior de Ingería de Sevilla cumple con estos requisitos.
Tarea DSI 1.7: Especificación de Requisitos de Operación y Seguridad
Los requisitos para la operación y seguridad del sistema, basándonos en la arquitectura
de red propuesta, definimos:
46 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Procedimientos de Seguridad y Control de Acceso: únicamente los alumnos
matriculados en la asignatura deben tener acceso al sistema. Los profesores
accederán al servidor de manera física. El despacho del profesor en el cual se
emplace el servidor debe estar cerrado con llave. El profesor responsable será el
encargado de la integridad de los datos de los alumnos. Cada acceso al sistema
por parte de los alumnos se reflejará en un log mostrado por pantalla. Para
asegurar la disponibilidad del trabajo de los alumnos se requerirá que este se
entregue además de manera telemática usando la Plataforma de Enseñanza
Virtual de la Universidad de Sevilla.
Procedimientos de Operación y Administración del Sistema: para la fase de
entrega de la PFED los alumnos tendrán disponible el acceso al sistema los días
previos al examen. Durante la evaluación del examen se les entregará a los
alumnos la versión del programa que les permitirá acceder al sistema para
evaluar su examen y se finalizará la posibilidad de acceso una vez concluido el
mismo. El profesor responsable será el encargado de habilitar e inhabilitar el
acceso de los alumnos y de obtener los resultados.
ACTIVIDAD DSI 2: DISEÑO DE LA ARQUITECTURA DE SOPORTE En este proyecto se utilizará la arquitectura de soporte ya existente en la Escuela
Superior de Ingeniería por lo que no es posible realizar un nuevo diseño de subsistemas
de soporte ni construir una nueva arquitectura.
Como ya hemos comentado en el apartado DSI 1.6 la arquitectura existente es suficiente
para comunicar satisfactoriamente nuestros nodos.
ACTIVIDAD DSI 3: DISEÑO DE CASOS DE USO REALES
Tarea DSI 3.1: Identificación de Clases Asociadas a un Caso de Uso
La relación entre las clases previstas (incluyendo las clases adicionales del apartado DSI
4.1) y los casos de uso se muestran en la tabla 38.
Caso de uso Clases asociadas
Registro PrincipalAlumno, Alumno, Ventana, Comunicación, AlumnoServidor, DataBase
Enviar trabajo Alumno, Fichero, Ventana, Comunicación, AlumnoServidor
Enviar examen Alumno, Fichero, Ventana, Comunicación AlumnoServidor
Ejecutar herramienta Ventana, Comunicación, AlumnoServidor, Database
Corregir apartado Ventana, Comunicación, AlumnoServidor, Database
Obtener notas AlumnoServidor, DataBase
Comprobar nombre de usuario DataBase
Almacenar datos DataBase
Almacenar ficheros AlumnoServidor
47 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Consultar datos DataBase
Imprimir fichero de notas DataBase, AlumnoServidor
Generar informe de plagio PrincipalPlagio, FuncionesPlagio
Obtener informe de plagio PrincipalPlagio, FuncionesPlagio
Tabla 38. Relación Caso de uso – Clases asociadas
Tarea DSI 3.2: Diseño de la Realización de los Casos de Uso
A continuación vamos a especificar mediante diagramas de secuencia cuál es el proceso
de ejecución y la interacción entre las clases indicadas en la tabla 38.
Figura 15. Diagrama de secuencia. Casos de uso: Registro, enviar trabajo, enviar
examen, comprobar nombre de usuario, almacenar datos, almacenar ficheros
48 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Figura 16. Casos de uso: Ejecutar herramienta, corrige apartado
Figura 17. Casos de uso: Obtener notas, consultar datos, generar informe de notas,
imprimir fichero de notas
49 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Figura 18. Casos de uso: Generar informe, obtener informe
Tarea DSI 3.3: Revisión de la Interfaz de Usuario
Todos los elementos de la interfaz de usuario que fueron analizados en la tarea ASI 8
han sido revisados y verificados satisfactoriamente.
Tarea DSI 3.4: Revisión de Subsistemas de Diseño e Interfaces
Los subsistemas definidos en la actividad DSI 1.5 han sido revisados y considerados
válidos.
ACTIVIDAD DSI 4: DISEÑO DE CLASES
Tarea DSI 4.1: Identificación de Clases Adicionales
Tras una revisión se considera necesario incluir clases adicionales asignadas al requisito
del control de plagio. Como se especifica en el apartado ASI 1.2 es necesario que el
servidor tenga dos sistemas operativos distintos: Linux para la ejecución del sistema
corrector y Windows para el sistema de control de plagio. Por eso para completar el
diagrama del apartado ASI 5.1 añadimos las clases especificadas en la figura 19.
Figura 19. Clases adicionales
Es este sistema adicional identificamos dos clases. Una clase principal que ejecutará las
funciones auxiliares de la clase FuncionesPlagio. Esta segunda clase será la encargada de
evaluar a los alumnos uno por uno, ejecutando el software SIM, y generar la información
de plagio.
50 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Tarea DSI 4.2: Diseño de Asociaciones y Agregaciones
No hay nuevas asociaciones ni agregaciones.
Tarea DSI 4.3: Identificación de Atributos de las Clases
Completando lo expuesto en el apartado ASI 5.1 (incluyendo las nuevas clases definidas)
será necesario que se dispongan de los siguientes atributos:
PricipalAlumno
o alumno, Alumno que ejecuta el sistema.
o ventana, objeto que contiene la interfaz gráfica.
o comunicación, objeto que contiene la información de comunicación con
el servidor.
Alumno
o UVUS, identificación del alumno.
o fichero, Fichero con el trabajo del alumno.
Fichero
o file, objeto con la información del fichero comprimido con el código del
alumno.
o byteArray, cadena de bytes que forman el fichero.
o size, tamaño del fichero en bytes.
Temporizador
o timer, objeto que mide la temporización
Ventana
o botones, botones que incluye la interfaz gráfica.
o etiqueta, objeto Label con la información correspondiente al apartado
seleccionado.
o texto, cuadro de texto con la información del resultado de la última
ejecución realizada.
Comunicación
o IPServidor, cadena de caracteres con la IP del servidor a conectar.
o Socket, socket utilizado para la comunicación.
HiloAlumno
o opción, entero con la opción elegida de la interfaz gráfica
o ventana, objeto que contiene la interfaz gráfica utilizada
PrincipalServidor
o comunicacion, objeto con los métodos para comunicarse con el alumno
DataBase
o basicDBObject, elemento de una colección de una base de datos
MongoDB.
o DBCollection, colección de una base de datos MongoDB.
AlumnoServidor
o UVUS, identificador del alumno conectado
o comunicacion, objeto con las funciones para la comunicación con el
alumno.
51 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
o dataBase, base de datos donde almacenar los resultados.
HiloServidor
o opción, opción elegida por el alumno conectado.
o alumno, alumno conectado.
o dataBase, base de datos a utilizar.
o comunicación, objeto con las funciones para la comunicación con el
alumno.
PrincipalPlagio:
o funciones, objeto que ejecutará las funciones requeridas.
o directorioTrabajos, objeto File del que se obtendrán los ficheros con el
código fuente de los alumnos.
FuncionesPlagio:
o listaAlumnos, lista con todos los UVUS de los alumnos a evaluar.
o listaApartados, lista con los apartados a evaluar.
Tarea DSI 4.4: Identificación de Operaciones de las Clases
El comportamiento de las clases de diseño es el especificado en los apartados ASI 5.1 y
DSI 4.1 no se han añadido nuevas operaciones ni se han modificado las ya especificadas.
Tarea DSI 4.5: Diseño de la Jerarquía
La jerarquía de clases utilizadas en el diseño se ha revisado y se ha considerado viable.
Solo existe herencia en la implementación de la clase Thread de Java para adaptarla a
las operaciones realizadas por los hilos de nuestro sistema.
Tarea DSI 4.6: Descripción de Métodos de las Operaciones
En esta tarea vamos a detallar los métodos que deben implementarse para la realización
de las operaciones de las distintas clases. Especificaremos los métodos mostrados en las
figuras 12 y 18 cuyos nombres no sean suficientes para saber su funcionalidad. Para
mayor detalle puede consultar el Anexo 2 en el cual está disponible el código fuente
utilizado con la documentación Javadoc correspondiente.
PricipalAlumno
o main(), método de ejecución principal.
Temporizador
o start(), inicia el temporizador.
o cancelar(), cancela la acción del temporizador
Ventana
o setTexto(), establece el texto a mostrar en el cuadro de texto.
o addButttons(), añade los botones a la interfaz gráfica.
o delButtons(), elimina los botones de la interfaz gráfica.
o addTick(), añade una imagen de confirmación a un apartado.
o delTick(), elimina la imagen de confirmación.
o setBuffering(), añade la animación de buffering.
o delBuffering(), elimina la animación de buffering.
52 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
o registraAlumno(), manda la petición de registrar y enviar los ficheros de
un alumno.
o peticiónHerramienta(), manda la petición de ejecutar la herramienta de
comprobación.
o peticiónApartado(), manda la petición de corregir un apartado.
PrincipalServidor
o main(). Método de ejecución principal.
DataBase
o creaLista(), crea una nueva colección en la base de datos con la lista de
alumnos.
o compruebaAlumno(), confirma si un alumno se encuentra en la lista.
o borraDatos(), elimina los datos de la base de datos.
o publicaNota(), guarda la nota de un alumno correspondiente a un
apartado.
o imprimeNotas(), imprime el fichero de notas.
AlumnoServidor
o registraAlumno(), comprueba si es un alumno válido y almacena sus
ficheros.
o corrigeHerramienta(), ejecuta la herramienta para un alumno
determinado.
o corrigeApartado(), corrige un apartado para un alumno determinado.
o compruebaFicheros(), comprueba que los ficheros pertenecientes al
enunciado del examen no han sido modificados.
PrincipalPlagio:
o main(), método de ejecución principal.
FuncionesPlagio:
o obtieneLista(), lee del sistema de ficheros la lista con los identificadores
de los alumnos a evaluar.
o compruebaPlagio(), genera el fichero con la información de plagio.
Tarea DSI 4.7: Especificación de Necesidades de Migración y Carga Inicial de Datos
Para la carga inicial de los datos se deberán almacenar en la base de datos los datos de
los usuarios que pueden utilizar el sistema para evitar accesos indebidos. Estos datos
son leídos de un fichero de texto plano externo que contendrá la lista de los alumnos
que estarán identificados por nombre, apellidos y UVUS.
ACTIVIDAD DSI 6: DISEÑO FÍSICO DE DATOS
Tarea DSI 6.1: Diseño del Modelo Físico de Datos
El diseño del modelo de datos de nuestra base de datos será muy simple. Como se
muestra en la figura 20 solo existirá una colección. En esta colección se almacenará un
documento por alumno. La información almacenada en este documento será su UVUS
como identificador único, su nombre y apellidos y la nota de los apartados que
complete. Al ser una base de datos NoSQL los alumnos pueden tener un número de
campos variable en los documentos que los identifican.
53 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
En cuanto al sistema de almacenamiento de ficheros debe seguir una estructura fija para
que pueda ser leída de manera automática. Esta estructura se definirá durante el
proceso CSI junto con la realización de la codificación.
Clase FP2
UVUSPK
Apellidos
Nombre
Notas
Figura 20. Colección a utilizar
Tarea DSI 6.2: Especificación de los Caminos de Acceso a los Datos
En nuestro sistema no hay que gestionar un tratamiento crítico de los datos ya que los
alumnos solo accederán a sus datos dentro del sistema, no hay acceso a datos
compartidos. El servidor se encontrará preparado para atender peticiones simultáneas
asegurando la consistencia de los datos.
Tarea DSI 6.3: Optimización del Modelo Físico de Datos
El modelo físico de datos ya se encuentra optimizado y no es necesario realizar
ninguna modificación sobre el mismo.
Tarea DSI 6.4: Especificación de la Distribución de Datos
En nuestro sistema de información la totalidad de los datos se almacenarán en el
servidor (sin incluir las copias de seguridad). Tanto el sistema gestor de los datos como
el sistema de ficheros con los trabajos recibidos se almacenarán en este nodo.
ACTIVIDAD DSI 7: VERIFICACIÓN Y ACEPTACIÓN DE LA ARQUITECTURA DEL
SISTEMA
Tarea DSI 7.1: Verificación de las Especificaciones de Diseño
Se ha revisado todo el sistema, incluyendo el modelo de datos, último en incorporarse.
No se han encontrado inconsistencias y por lo tanto las especificaciones de diseño están
verificadas.
Tarea DSI 7.2: Análisis de Consistencia de las Especificaciones de Diseño
Se vuelve a analizar lo comentado en la tarea ASI 9.2 y siguiendo las indicaciones
reflejadas en el documento de MÉTRICA Versión 3 [30] aseguramos que:
Arquitectura del Sistema / Subsistemas:
54 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
- Cada subsistema de diseño está asociado al menos con un nodo del
particionamiento físico del sistema de información.
Arquitectura del Sistema / Modelo Físico de Datos:
- Todos los elementos definidos en el Modelo Físico de Datos Optimizado
se incorporan, al menos, en un esquema físico de datos.
- Cada esquema del Modelo Físico de Datos está asociado con un nodo
del particionamiento físico del sistema de información.
Arquitectura del Sistema / Entorno Tecnológico del Sistema de Información:
- Cada nodo del particionamiento del sistema de información está
soportado por el entorno tecnológico.
- Se da soporte a todas las necesidades de comunicaciones entre nodos.
Modelo de Clases / Modelo Físico de Datos:
- Los elementos del modelo físico de datos corresponden con los
elementos utilizados por las clases del diseño detallado, tanto de los
subsistemas específicos como de soporte.
Modelo de Clases / Diagramas Dinámicos
- Cada mensaje entre objetos se corresponde con una operación de una
clase, y todos los mensajes se envían a las clases correctas, incluyendo
las clases de interfaz y la navegación entre ventanas.
- Cada mensaje entre subsistemas se corresponde con una operación de
una clase del subsistema destino.
- La clase que recibe un mensaje con petición de datos tiene capacidad
para proporcionar esos datos.
- Cada objeto del diagrama de interacción de objetos tiene una
correspondencia en el modelo de clases.
- Todas las clases, atributos y métodos identificados en la interfaz de
usuario tienen su correspondencia con algún atributo, método o clase
en el modelo de clases.
Tarea DSI 7.3: Aceptación de la Arquitectura del Sistema
La arquitectura se considera válida y por lo tanto se acepta su instalación.
ACTIVIDAD DSI 8: GENERACIÓN DE ESPECIFICACIONES DE CONSTRUCCIÓN
Tarea DSI 8.1: Especificación del Entorno de Construcción
El entorno tecnológico y de construcción es el mismo que el que ya se describió en la
tarea DSI 1.6. No es necesario especificar nuevas características.
Tarea DSI 8.2: Definición de Componentes y Subsistemas de Construcción
Podemos identificar cada componente del modelado de clases como un componente o
subsistema de construcción. Estos componentes serán agrupados de la siguiente forma:
Subsistema cliente para la ejecución de la herramienta:
o Contiene las clases PrincipalAlumno, Alumno, Fichero, Ventana,
Temporizador, HiloAlumno y Comunicación.
55 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
o Existe dependencia circular entre las clases Ventana e HiloAlumno. La
clase ventana necesita iniciar objetos de clase HiloAlumno y en dichos
hilos es necesario modificar el contenido de la interfaz gráfica.
o Estas clases serán agrupadas en un mismo paquete que posteriormente
será exportado para su ejecución como un fichero jar.
Subsistema cliente para la corrección del examen:
o Contendrá las mismas clases que en el caso anterior pero con las
modificaciones necesarias para la corrección de los apartados del
examen. Es decir, en la interfaz gráfica se mostrarán los botones
correspondientes a la corrección de cada uno de los apartados que
conformen el examen (con sus funciones asociadas) en lugar del botón
para ejecutar la herramienta.
Subsistema servidor para la corrección automática:
o Contiene las clases PrincipalServidor, AlumnoServidor, DataBase,
HiloServidor y Comunicación.
o Se necesitarán las librerías disponibles para la gestión de MongoDB con
el lenguaje de programación Java [26].
o Estas clases serán agrupadas en un mismo paquete que posteriormente
será exportado para su ejecución como un fichero jar.
Subsistema para la detección de plagio.
o Contiene las clases PrincipalPlagio y FuncionesPlagio.
o Estas clases serán agrupadas en un mismo paquete que posteriormente
será exportado para su ejecución como un fichero jar.
Tarea DSI 8.3: Elaboración de Especificaciones de Construcción
A lo largo de este documento se ha detallado de manera suficiente cada componente
del sistema. No es necesario añadir ninguna información técnica sobre el desarrollo que
se va a seguir. Para cualquier duda puede consultar el resultado final del código
desarrollado mostrado en el Anexo 2.
Tarea DSI 8.4: Elaboración de Especificaciones del Modelo Físico de Datos
Como ya hemos dicho, para el modelo de datos se utilizara una base de datos NoSQL,
en particular MongoDB, que permite arquitecturas de datos más flexibles y eficientes.
El modelo es el que introdujimos en la tarea DSI 6.1.
ACTIVIDAD DSI 9: DISEÑO DE LA MIGRACIÓN Y CARGA INICIAL DE DATOS En este proyecto no es necesario la migración de datos desde otro sistema ya existente.
En cuanto a la carga inicial de datos, se detalla en la tarea DSI 4.7. No es necesario
especificar un escenario específico ni un proceso en particular. El profesor de la
asignatura será el encargado de aportar la lista de los alumnos en el formato adecuado.
Este formato se especificará en la construcción del sistema de información.
56 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
ACTIVIDAD DSI 10: ESPECIFICACIÓN TÉCNICA DEL PLAN DE PRUEBAS
Tarea DSI 10.1: Especificación del Entorno de Pruebas
En esta tarea se detalla el entorno en el que se realizarán las pruebas del sistema. En
cuanto al entorno hardware, software y de comunicaciones será el mismo que el
detallado en la tarea ASI 10.2. Hay que tener en cuenta las restricciones ofrecidas por la
red utilizada.
Es posible que el proxy del Centro de Cálculo descarte la comunicación si usamos el
puerto TCP 80. También es posible que el firewall del departamento de telemática filtre
conexiones entrantes usando puertos desconocidos. Finalmente es necesario
comprobar que el firewall de los equipos finales tienen las excepciones adecuadas para
permitir la comunicación.
No es necesario especificar ningún procedimiento de emergencia o recuperación de
datos ya que en las pruebas no se trabajará con información crítica.
Una vez finalizado el proceso de pruebas es necesario devolver al sistema a su estado
original.
Tarea DSI 10.2: Especificación Técnica de Niveles de Prueba
A continuación, en las tablas 39-58 especificaremos en cada uno de los niveles de prueba
las operaciones a realizar, el objetivo de las mismas y el resultado que debemos obtener
para que la prueba se considere completada con éxito.
Pruebas unitarias:
Prueba PU-01 Objetivo Comprobar el correcto funcionamiento de los métodos descritos en
el apartado DSI 4.6. Resultado Cada uno de los métodos deberá realizar la funcionalidad descrita
correctamente. Devolviendo los resultados y tipos esperados. Tabla 39. PU-01
Prueba PU-02 Objetivo Comprobar el correcto almacenamiento de los datos de un alumno. Resultado El sistema obtendrá de manera satisfactoria los datos de un alumno
desde la lista de alumnos. Tabla 40. PU-02
Prueba PU-03 Objetivo Manejar errores de conexión. Resultado Si alguna de las partes no se encuentra disponible se mostrará un
mensaje de error. Tabla 41. PU-02
57 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Prueba PU-04 Objetivo Comprobar accesos indebidos. Resultado Un usuario cuyos datos no se encuentren en el sistema se le denegará
el acceso. Tabla 42. PU-03
Prueba PU-05 Objetivo Almacenamiento de datos. Resultado Se almacenarán correctamente en el servidor los ficheros
correspondientes a un alumno. Tabla 43. PU-04
Prueba PU-06 Objetivo Gestión de la base de datos. Resultado Se guardará correctamente tanto los datos como la nota
perteneciente a un alumno en la base de datos. Tabla 44. PU-05
Prueba PU-07 Objetivo Llamadas al sistema operativo. Resultado El programa servidor realizará correctamente las llamadas al sistema
operativo. Debe crear directorios satisfactoriamente y ejecutar software externo al proyecto.
Tabla 45. PU-06
Prueba PU-08 Objetivo Interfaz gráfica. Resultado Se mostrará correctamente la interfaz gráfica con las opciones
correspondientes a la ejecución de la herramienta o la corrección del examen.
Tabla 46. PU-07
Pruebas de integración:
Prueba PI-01 Objetivo Registro en el sistema Resultado Un usuario válido entrará en el sistema y almacenará sus datos
satisfactoriamente Tabla 47. PI-01
Prueba PI-02 Objetivo Ejecución de la herramienta satisfactoriamente Resultado Un usuario válido ejecutará la herramienta y obtendrá un mensaje de
confirmación satisfactoria. Guardándose su nota en la base de datos. Tabla 48. PI-02
58 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Prueba PI-03 Objetivo Ejecución de la herramienta fallida Resultado Un usuario válido ejecutará la herramienta y obtendrá mensaje de
error junto con el informe correspondiente. Tabla 49. PI-03
Prueba PI-04 Objetivo Corrección de un apartado satisfactoriamente Resultado Un usuario válido pulsará el botón de la interfaz gráfica
correspondiente a un apartado del examen y obtendrá un mensaje de confirmación satisfactoria. Guardándose su nota en la base de datos.
Tabla 50. PI-04
Prueba PI-05 Objetivo Corrección de un apartado fallida Resultado Un usuario válido pulsará el botón de la interfaz gráfica
correspondiente a un apartado del examen y obtendrá un mensaje de error junto con el informe correspondiente.
Tabla 51. PI-05
Pruebas del sistema:
Prueba PS-01 Objetivo Funcionamiento completo Resultado El sistema deberá realizar correctamente de manera local la fase de
corrección de la herramienta y del examen completo para un alumno determinado.
Tabla 52. PS-01
Prueba PS-02 Objetivo Concurrencia Resultado El sistema aceptará la conexión de más de alumno simultáneamente.
Tabla 53. PS-02
Prueba PS-03 Objetivo Funcionamiento ante situaciones de estrés Resultado El sistema debe funcionar correctamente ante un número elevado de
usuarios utilizando el sistema. Se validará si el sistema responde satisfactoriamente con 150 usuarios simultáneos.
Tabla 54. PS-03
59 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Diseño del Sistema de Información
(DSI)
Prueba PS-04 Objetivo Impresión de notas Resultado El sistema imprimirá correctamente las notas en los formatos
requeridos. Tabla 55. PS-04
Prueba PS-05 Objetivo Generación informe de plagio Resultado El sistema generará correctamente el informe de plagio de un
conjunto de trabajos de alumnos. Tabla 56. PS-05
Pruebas de implantación:
Prueba PImp-01 Objetivo Funcionamiento en entorno real Resultado El sistema debe funcionar correctamente usando como servidor el
equipo del despacho de un profesor y como cliente un equipo del Centro de Cálculo.
Tabla 57. PImp-01
Pruebas de aceptación:
Prueba PA-01 Objetivo Aceptación del profesorado Resultado Los profesores involucrados en la asignatura de FP2 deben validar el
sistema. Tabla 58. PA-01
ACTIVIDAD DSI 11: ESTABLECIMIENTO DE REQUISITOS DE IMPLANTACIÓN
Tarea DSI 11.1: Especificación de Requisitos de Documentación de Usuario
Una vez desarrollado el software, se distribuirá en formato PDF un manual de usuario
para la corrección de la PFED y otro en formato físico para el examen. Este manual
explicará a los alumnos el método de instalación y utilización del servicio.
A parte se realizará otro manual en formato electrónico para los profesores en el que se
detalle la instalación y funcionamiento del servidor.
Tarea DSI 11.2: Especificación de Requisitos de Implantación
Para la implantación del sistema será necesario disponer del equipamiento descrito en
el apartado ASI 10.2.
60 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Construcción del Sistema de
Información
Para la utilización del sistema no será necesaria ninguna formación específica ni para los
alumnos ni para los profesores ya que se asume que tienen los conocimientos básicos
para su correcta utilización.
ACTIVIDAD DSI 12: APROBACIÓN DEL DISEÑO DEL SISTEMA DE
INFORMACIÓN
Tarea DSI 12.1: Presentación y Aprobación del Diseño del Sistema de Información
El sistema ha sido presentado y aprobado satisfactoriamente por el profesor encargado
de la supervisión del proyecto.
Construcción del Sistema de Información El objetivo de este proceso [31] es la elaboración del sistema. Se desarrollará el código
correspondiente de todos los componentes y procedimientos. Además se elaborarán los
manuales de usuario y se realizarán todas las pruebas especificadas anteriormente.
En la figura 21 podemos observar cuáles son las actividades a realizar en este proceso.
Primero se asegurará la disponibilidad de la infraestructura necesaria para la
construcción del sistema.
A continuación se desarrollará el código y se ejecutarán las pruebas unitarias y de
integración. Se realiza la integración del sistema y finalmente se elaboran los manuales
de usuario y la formación necesaria para los mismos.
Figura 21. Estructura CSI
61 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Construcción del Sistema de
Información
ACTIVIDAD CSI 1: PREPARACIÓN DEL ENTORNO DE GENERACIÓN Y
CONSTRUCCIÓN
Tarea CSI 1.1: Implantación de la Base de Datos Física o Ficheros
Para implantar la base de datos que vamos a utilizar seguimos los pasos que nos indica
la documentación online de MongoDB [18]. Tanto la carga inicial de los datos en la base
de datos como la creación del sistema de ficheros a utilizar se desarrollarán con el
proyecto más adelante.
Tarea CSI 1.2: Preparación del Entorno de Construcción
Para comenzar la construcción del sistema debemos instalar los siguientes componentes
(especificado en la tarea DSI 1.6):
Biblioteca de adaptación de MongoDB a Java [26].
Herramienta y código de un alumno de ejemplo.
Entorno de desarrollo Eclipse.
Equipo de desarrollo informático. En este caso se utilizará un equipo con un
procesador Intel Core i7 a 2.2 GHz y 8 GB de RAM.
ACTIVIDAD CSI 2: GENERACIÓN DEL CÓDIGO DE LOS COMPONENTES Y
PROCEDIMIENTOS
Tarea CSI 2.1: Generación del Código de Componentes
En esta tarea se realiza el desarrollo del código de cada uno de los componentes citados
en la tarea DSI 8.2. Para ello seguimos los estándares de nomenclatura y codificación
recogidos en el catálogo de normas.
El proceso de generación del código se detalla en el bloque 3. Una vez realizado se
corrigen los errores de sintaxis y se compila la solución. La versión final del código puede
verse en el bloque 6 Anexo 2.
Tarea CSI 2.2: Generación del Código de los Procedimientos de Operación y Seguridad
En esta tarea se codifica la parte del sistema correspondiente a los procedimientos de
operación en el mismo, así como los procedimientos de seguridad y control de acceso.
ACTIVIDAD CSI 3: EJECUCIÓN DE LAS PRUEBAS UNITARIAS
Tarea CSI 3.1: Preparación del Entorno de las Pruebas Unitarias
El objetivo de esta tarea es el de preparar en el entorno para la realización de las pruebas
unitarias. En este caso el entorno será el mismo que el de desarrollo que fue descrito en
la tarea DSI 8.1.
Tarea CSI 3.2: Realización y Evaluación de las Pruebas Unitarias
En esta tarea se han realizado las pruebas unitarias especificadas en la tarea DSI 10.2.
En la tabla 59 podemos ver un resumen de los resultados obtenidos.
62 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Construcción del Sistema de
Información
Prueba Objetivo Incidencias Resultado
PU-01 Verificación de métodos
Ninguna Superada
PU-02 Verificación de obtención de datos.
Para el correcto funcionamiento la lista debe seguir el formato: APELLIDOS, NOMBRE uvus
Superada
PU-03 Verificación de errores de conexión
Ninguna. Superada
PU-04 Comprobar accesos indebidos
Ninguna. Superada
PU-05 Almacenamiento de datos
El sistema no permite el acceso si no existen los ficheros del trabajo del alumno.
Superada
PU-06 Gestión de la base de datos
Almacenamiento sin incidencias. Obtención de datos con formato JSON.
Superada
PU-07 Llamadas al sistema operativo
Provocan errores de ejecución si no se bloquea el proceso principal hasta el fin de la acción del SO.
Superada
PU-08 Interfaz gráfica Ninguna Superada Tabla 59. Resumen de resultados de las pruebas unitarias.
ACTIVIDAD CSI 4: EJECUCIÓN DE LAS PRUEBAS DE INTEGRACIÓN
Tarea CSI 4.1: Preparación del Entorno de las Pruebas de Integración
El entorno es el mismo que el de las pruebas unitarias del apartado CSI 3.1.
Tarea CSI 4.2: Realización de las Pruebas de Integración
Para esta tarea se realizan las pruebas de integración en la tabla 60 podemos ver el
resumen de los resultados obtenidos.
Prueba Objetivo Incidencias Resultado
PI-01 Registro en el sistema
Ninguna Superada
PI-02 Ejecución de la herramienta satisfactoriamente
Para que el servidor pueda ejecutar la herramienta es necesario que la ejecución de la herramienta se realice en el directorio del trabajo del alumno. Para analizar errores se debe ejecutar en modo “silencioso” donde solo se muestren los errores. La herramienta solo funciona en un SO de 32 bits.
Superada
PI-03 Ejecución de la herramienta fallida
Ninguna Superada
63 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Construcción del Sistema de
Información
PI-04 Corrección de un apartado satisfactoriamente
Mismas limitaciones que para la ejecución de la herramienta.
Superada
PI-05 Corrección de un apartado fallida
Ninguna Superada
Tabla 60. Resumen de resultados de las pruebas de integración
Tarea CSI 4.3: Evaluación del Resultado de las Pruebas de Integración
Todas las pruebas se han superado con éxito. Los problemas existentes se han localizado
y corregido satisfactoriamente. No deben llevarse a cabo nuevas acciones para corregir
la codificación del sistema.
ACTIVIDAD CSI 5: EJECUCIÓN DE LAS PRUEBAS DEL SISTEMA
Tarea CSI 5.1: Preparación del Entorno de las Pruebas del Sistema
No se ha modificado el entorno desde la tarea CSI 3.1
Tarea CSI 5.2: Realización de las Pruebas del Sistema
A continuación se comprueba el funcionamiento general del sistema con la integración
de todos los subsistemas y componentes. En la tabla 61 se muestra un resumen de los
resultados.
Prueba Objetivo Incidencias Resultado
PS-01 Funcionamiento completo
Se ha comprobado que todos los aspectos del sistema funcionan correctamente usando un usuario de ejemplo.
Superada
PS-02 Concurrencia Ninguna Superada
PS-03 Situación de estrés
Se realizan pequeñas modificaciones en el código para que automáticamente se realice la transferencia de un fichero y el almacenamiento de una nota. Mediante un script se ejecuta 150 veces la aplicación del cliente de manera simultánea. Aunque el sistema se ralentiza considerablemente se almacenan todos los datos satisfactoriamente.
Superada
PS-04 Impresión de notas
Hay que extraer los objetos JSON e imprimirlos o bien como una variable JavaScript para su representación en un documento HTML o extraer sus campos para su representación en una tabla Excel
Superada
PS-05 Informe de plagio
Necesita SO Windows Superada
Tabla 61. Resumen de resultados de las pruebas del sistema
64 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Implantación y Aceptación del Sistema
(IAS)
Tarea CSI 5.3: Evaluación del Resultado de las Pruebas del Sistema
El resultado de las pruebas ha sido satisfactorio. Los resultados han sido los esperados y
no se requieren acciones adicionales. Para finalizar con la realización de las pruebas
comprobaremos en el proceso de implantación del sistema que el sistema funciona en
el escenario final para que sea validado por los profesores implicados en la asignatura.
ACTIVIDAD CSI 6: ELABORACIÓN DE LOS MANUALES DE USUARIO
Tarea CSI 6.1: Elaboración de los Manuales de Usuario
Para esta tarea realizamos los manuales de usuario necesarios para la utilización del
sistema. Realizamos un manual para los alumnos, explicando la instalación y utilización
de la parte del cliente y otro manual para los profesores. En este segundo manual, más
breve, indicamos cómo instalar y poner en marcha el servidor para obtener los
resultados finales.
Ambos manuales están disponibles en el Anexo 1.
ACTIVIDAD CSI 7: DEFINICIÓN DE LA FORMACIÓN DE USUARIOS FINALES Para una utilización eficiente del sistema no es necesario realizar una formación de los
usuarios. Para utilizar nuestro sistema es suficiente con seguir los pasos detallados en el
manual de usuario correspondiente.
ACTIVIDAD CSI 8: CONSTRUCCIÓN DE LOS COMPONENTES Y
PROCEDIMIENTOS DE MIGRACIÓN Y CARGA INICIAL DE DATOS Cómo ya se comentó en la actividad DSI 9 no será necesario la migración de datos desde
ningún sistema existente por lo tanto no es necesario desarrollar otro sistema destinado
a este objetivo.
ACTIVIDAD CSI 9: APROBACIÓN DEL SISTEMA DE INFORMACIÓN
Tarea CSI 9.1: Presentación y Aprobación del Sistema de Información
El sistema ha sido presentado al personal encargado de su revisión y ha sido aprobado
para su utilización final en la evaluación de la asignatura de Fundamentos de
Programación 2 del curso 2013-2014.
Implantación y Aceptación del Sistema (IAS) El objetivo de este proceso [32] es la entrega y aceptación del sistema en su totalidad.
También se especifican las actividades a realizar para el paso a producción del sistema.
Una vez se prepara la infraestructura para la implantación del sistema y se realiza la
instalación de software oportuna se pasa a la realización de las pruebas de implantación
y de aceptación.
Como se puede ver en la figura 22 en paralelo a estas actividades se realiza la
preparación del proceso de mantenimiento y el establecimiento del acuerdo de nivel de
servicio, si lo hubiese.
Ya que este proyecto se trata de un Trabajo Final de Grado no se realizarán las
actividades IAS 7, 8 y 10. El mantenimiento del sistema se realizará por parte del
65 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Implantación y Aceptación del Sistema
(IAS)
profesorado y no se realizará un acuerdo de nivel de servicio. En nuestro caso particular
no existe un escenario de producción del sistema por lo que la actividad IAS 10 carece
de sentido.
Figura 22. Estructura IAS
ACTIVIDAD IAS 1: ESTABLECIMIENTO DEL PLAN DE IMPLANTACIÓN
Tarea IAS 1.1: Definición del Plan de Implantación
Una vez analizados los requisitos de implantación propuestos en el apartado DSI 11.2
junto con los requisitos de operación y seguridad del apartado DSI 1.7 definimos el plan
de implantación a seguir para nuestro sistema.
Como ya hemos comentado no es necesario una formación específica para los usuarios
del sistema por lo que no es necesario destinar ninguna jornada de trabajo a ello. La
infraestructura necesaria ya se encuentra operativa por lo que tampoco es objetivo de
este proyecto su preparación.
Será necesario dedicar al menos una jornada de trabajo a la instalación del software
necesario en el servidor. Debemos instalar tanto el sistema gestor de base de datos
como el software desarrollado. En el lado del cliente no será necesario instalar ningún
componente, solo ejecutar llegado el momento el software destinado al alumno.
Finalmente serán necesarias algunas jornadas más para realizar las pruebas de
implantación y solucionar los problemas que surjan. Con la aceptación del sistema
posterior se concluye la planificación.
Tarea IAS 1.2: Especificación del Equipo de Implantación
El equipo de trabajo implicado en la implantación del sistema es el siguiente:
Usuarios finales. Los alumnos de la asignatura de Fundamentos de Programación
2 que se presenten a la evaluación serán los indicados para la utilización del
sistema. Se les considerará con un perfil básico y sin conocimientos del sistema.
66 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Implantación y Aceptación del Sistema
(IAS)
Por lo tanto, no tendrán ninguna responsabilidad a parte de la utilización del
sistema para ser evaluados.
Equipo técnico. Al ser un proyecto académico, el equipo técnico estará formado
solo por mí, Andrés Martínez Gotor. Seré el encargado de la implantación del
sistema y de asegurar el correcto funcionamiento del mismo. El equipo técnico
debe estar presente durante todas las fases de la implantación y uso del sistema
para poder solventar los problemas que pudiesen surgir en la ejecución real del
mismo.
Responsable de mantenimiento. Una vez el sistema haya sido probado con éxito
durante la primera convocatoria, el profesorado de la asignatura y en especial el
coordinador Antonio Jesús Sierra Collado, serán los encargados del
mantenimiento del sistema para convocatorias posteriores.
ACTIVIDAD IAS 2: FORMACIÓN NECESARIA PARA LA IMPLANTACIÓN Como especificamos en la actividad CSI 7 no será necesario una formación específica
para los usuarios implicados en este sistema por lo que no se detallara un plan de
formación.
ACTIVIDAD IAS 3: INCORPORACIÓN DEL SISTEMA AL ENTORNO DE
OPERACIÓN
Tarea IAS 3.1: Preparación de la Instalación
Comprobamos que la arquitectura disponible cumple todos los requisitos excepto que
en el equipo servidor disponemos de la versión 1.6 de Java Runtime Enviroment
mientras que la versión mínima necesaria para ejecutar el sistema es la 1.7. Una vez
solucionado este aspecto y preparado el entorno se procede a instalar el sistema.
Tarea IAS 3.2: Realización de la Instalación
La instalación de nuestro proyecto es bastante sencilla. En el servidor basta con seguir
los pasos que nos ofrece la documentación de MongoDB [27] para su instalación y
descomprimir el sistema de ficheros con el programa servidor del sistema. En su interior
se encuentra el ejecutable para ponerlo en marcha tal como se detalla en el manual de
usuario.
ACTIVIDAD IAS 4: CARGA DE DATOS AL ENTORNO DE OPERACIÓN
Tarea IAS 4.1: Migración y Carga inicial de Datos
El sistema realiza la carga inicial de datos con los usuarios de la lista sin incidencias. No
se realiza migración de datos.
ACTIVIDAD IAS 5: PRUEBAS DE IMPLANTACIÓN DEL SISTEMA
Tarea IAS 5.1: Preparación de las Pruebas de Implantación
Para poder realizar las pruebas de implantación es necesario tener disponible un equipo
de los pertenecientes al Centro de Cálculo. Preferiblemente se utilizará uno
perteneciente al aula donde presumiblemente se realizará el examen aunque no es un
factor crítico ya que, aunque los equipos de las distintas aulas pueden diferenciarse en
aspectos hardware, todos utilizan el mismo sistema operativo con el mismo software.
67 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Implantación y Aceptación del Sistema
(IAS)
También será necesario la colaboración del profesor encargado de la supervisión del
sistema para poder utilizar el equipo de su despacho.
Tarea IAS 5.2: Realización de las Pruebas de implantación
La única prueba de implantación definida se trata de verificar el funcionamiento del
sistema en el escenario real descrito en la tarea IAS 5.1. Al realizar estas pruebas
comprobamos que, como se indicó en la tarea DSI 10.1, para que el sistema pueda
comunicarse satisfactoriamente es necesario que se utilice un puerto TCP distinto del
80 (en nuestro caso utilizaremos el 8888) y que el firewall del equipo del servidor admita
las conexiones entrantes.
Una vez solucionados los problemas de comunicación que pudieran existir
comprobamos que el sistema funciona sin ningún problema. Sólo permite el acceso a
los usuarios de la lista cumpliéndose los requisitos de seguridad y el rendimiento es
satisfactorio, pudiendo realizar todas las funciones del cliente en el orden de varios
segundos.
Tarea IAS 5.3: Evaluación del Resultado de las Pruebas de Implantación
El resultado de las pruebas de implantación ha sido satisfactorio. Se han superado con
éxito y no es necesario la realización de ninguna acción adicional.
ACTIVIDAD IAS 6: PRUEBAS DE ACEPTACIÓN DEL SISTEMA
Tarea IAS 6.1: Preparación de las Pruebas de Aceptación
No es necesario preparar un escenario para las pruebas de aceptación.
Tarea IAS 6.2: Realización de las Pruebas de Aceptación
La prueba de aceptación definida en la tarea DSI 10.2 comprende la aceptación por parte
del profesorado del sistema desarrollado. La prueba ha sido completada con éxito ya
que este ha dado su visto bueno al sistema y se ha autorizado su utilización.
Adicionalmente, el sistema ha sido aceptado por los alumnos que realizaron el examen
de la asignatura. Estos alumnos utilizaron el sistema durante la evaluación sin ningún
problema. Personalmente se supervisó la realización del mismo, respondiendo a las
dudas que surgían a los alumnos sobre la utilización del mismo.
Tarea IAS 6.3: Evaluación del Resultado de las Pruebas de Aceptación
Los resultados de las pruebas de aceptación han sido los esperados y se han completado
con éxito.
ACTIVIDAD IAS 9: PRESENTACIÓN Y APROBACIÓN DEL SISTEMA Como ya hemos comentado, el sistema ha sido presentado ante el profesorado de la
asignatura que realiza el rol de Comité de Dirección en este proyecto y el sistema ha sido
aprobado formalmente.
En este bloque hemos visto, de manera general, cuál ha sido todo el proceso de
evaluación, análisis, diseño, construcción e implantación del sistema siguiendo la
metodología de MÉTRICA Versión 3. En el siguiente bloque nos detendremos un poco
68 – BLOQUE 2. Aplicación MÉTRICA Versión 3 – Implantación y Aceptación del Sistema
(IAS)
más en la fase de construcción del mismo, analizando cada uno de los bloques que
hemos desarrollado para nuestro sistema. Además veremos los resultados de las
pruebas de ejecución del sistema. Concluiremos el bloque con las conclusiones del
proyecto y las líneas futuras de desarrollo, así como con un resumen de todo el proyecto
y las fuentes bibliográficas que hemos seguido durante la documentación.
69 – BLOQUE 3. Desarrollo del proyecto – Visión general
BLOQUE 3. Desarrollo del proyecto En este bloque vamos a describir los pasos realizados para la generación del código y
ejecución del sistema. Los aspectos de análisis y diseño que seguiremos han sido
analizados con la metodología de MÉTRICA Versión 3. Al margen de esta metodología,
para este bloque expondremos una explicación más detallada del desarrollo realizado y
del funcionamiento de cada una de las partes del sistema. Para ello nos basamos en el
código desarrollado (disponible en el Anexo 2).
Visión general Como ya hemos comentado, nuestro objetivo es desarrollar un sistema capaz de
corregir de manera automática la Práctica Final de Estructuras Dinámicas y por otra
parte el examen posterior realizado en el Centro de Cálculo de la ETSI. Para ello nuestro
sistema se dividirá en 3 grandes bloques: El servidor, el cliente para la PFED y el cliente
para el examen.
Figura 13. Diagrama de clases del sistema
A continuación vamos a detallar como hemos realizado cada uno de estos bloques. Para
el diseño de las clases del sistema nos hemos basado en el diagrama de clases de la
figura 13 que se encuentra detallado en la actividad ASI 5 del bloque 2.
70 – BLOQUE 3. Desarrollo del proyecto – Visión general
Cliente para la PFED Para el cliente de la PFED desarrollaremos las siguientes clases: PrincipalAlumno,
Alumno, Fichero, Ventana, Temporizador, Comunicación e HiloAlumno.
Lo primero será crear las clases más básicas, empezando por la clase Alumno. Esta es
una clase que dispondrá de los datos básicos del alumno: El UVUS y el fichero con su
trabajo. Solo se implementarán los métodos get para obtener estos dos atributos
privados y el constructor para instanciarlos.
La clase fichero es un envolvente de la clase File de Java. A parte del atributo File con el
fichero del alumno, esta clase contiene un byteArray con la cadena de bytes que forman
el fichero y un entero con el tamaño total del mismo.
El alumno dispondrá de un sistema de ficheros completo con su trabajo, no un solo
fichero, por eso mismo, en el constructor de esta clase se comprime la carpeta raíz del
trabajo en un fichero .zip que es el que se almacena y se envía al servidor.
Para realizar todas las llamadas al SO (como por ejemplo para comprimir un archivo)
utilizaremos los objetos Runtime y Proccess. Para asegurarnos de que no se produzcan
errores de ejecución esperamos a que haya finalizado el proceso por completo para
continuar con la ejecución. La estructura para la codificación de un proceso que ejecute
un comando del sistema operativo es siempre la misma:
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("zip -r PFED.zip "+rutaFichero);
p.waitFor();
La siguiente clase desarrollada es la clase Comunicación. Esta clase será muy parecida
tanto para el cliente como para el servidor. Una diferencia es que para la clase
Comunicación del cliente se le pasará como argumento la IP del servidor como un String
para realizar la conexión mientras que en el servidor se le pasará un objeto del tipo
ServerSocket que será el que acepte las conexiones.
Para esta clase primero se desarrollan los métodos de establecer y cerrar una conexión
(creando y cerrando el socket correspondiente). A continuación se realizan los métodos
para enviar o recibir un mensaje. Este mensaje puede ser de tipo entero o de tipo String.
En cada caso el tratamiento será diferente, pero en ambos casos se utilizará un objeto
OutputStream para escribir como un flujo de datos el objeto en el socket e InputStream
para leer un flujo de datos del socket. Por ejemplo:
public void enviaMensaje(String mensaje) throws IOException {
OutputStream ostream = socket.getOutputStream();
ObjectOutput s = new ObjectOutputStream(ostream);
s.writeObject(mensaje);
s.flush();
}
public String recibeString()throws IOException,ClassNotFoundException{
InputStream istream = socket.getInputStream();
ObjectInput in = new ObjectInputStream(istream);
return (String) in.readObject(); }
71 – BLOQUE 3. Desarrollo del proyecto – Visión general
Para finalizar esta clase creamos los métodos para enviar y recibir un fichero. El
procedimiento es similar en ambos casos. Primero enviamos o recibimos el tamaño del
fichero siguiendo las funciones antes desarrolladas y después el fichero en sí. Para enviar
el fichero primero se lee como un flujo de datos el objeto File y se guarda en la matriz
de bytes, luego se escribe esta matriz en el socket y se envía. Para recibir el proceso es
análogo: Se crea una matriz de bytes con el tamaño del fichero recibido y se lee del
socket hasta completar el fichero. Este se almacena en disco guardando la matriz de
bytes completa en un objeto de tipo FileOutputStream. Los detalles de estas funciones
pueden consultarse en el bloque 6 Anexo 2.
A continuación detallamos la clase Ventana. Se trata de una de las clases principales del
cliente y es la que nos muestra la interfaz gráfica del sistema. Para desarrollarla
utilizamos las librerías SWING de Java que nos permite disponer de los objetos
necesarios para crear los botones y cuadros de texto utilizados.
Para crear la interfaz gráfica, la clase Ventana debe extender la clase JFrame de Java y
lo primero que debemos hacer es definir los atributos que vamos a utilizar. Utilizaremos:
Un objeto JPanel que será la ventana en sí donde colocaremos el resto de los
elementos.
Un objeto JTextArea donde se mostrará la información del resultado de la
ejecución de los distintos apartados del sistema.
Varios objetos JButton con los botones que dispondrá nuestra interfaz.
Varios objetos JLabel con el título y las imágenes utilizadas.
En el constructor almacenaremos el objeto Alumno utilizado y la Comunicación
existente. A continuación instanciaremos y configuraremos el panel y cada uno de los
objetos antes descritos.
A continuación creamos los siguientes métodos para la gestión de los elementos
gráficos:
setTexto: establecen el texto de una etiqueta o del cuadro de texto.
addButtons/delButtons: muestran/ocultan los botones de la interfaz gráfica.
Aquí es necesario añadir a cada botón un ActionListener con la acción asociada
cuando se hace click sobre el botón correspondiente. En este caso será la de
crear un hilo que realice una determinada acción. Por ejemplo, para reenviar el
trabajo: // Función para el botón de reenviar
reenviarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Reenviando código:");
// Creamos animación buffering
setBuff();
new Hilo(ventana, 10);
}
});
72 – BLOQUE 3. Desarrollo del proyecto – Visión general
tick/delTick: muestra/oculta un tick de confirmación. En caso de existir varios
apartados para corregir se le pasa como argumento el apartado en el que se
debe colocar la imagen de confirmación.
setBuff/delBuff: muestra/oculta una imagen de buffering.
Una vez se han creado los métodos para controlar la interfaz gráfica, es necesario
desarrollar los métodos que realizarán cada una de las funciones asociadas a los
botones. En el caso de la corrección de la PFED habrá 2 funciones:
registraAlumno: será la función encargada de enviar el trabajo del alumno.
Consta de 2 pasos:
o Establecer la conexión, enviar al servidor la acción que debe realizar y el
UVUS del alumno mediante el método enviaMensaje de la clase
Comunicación. En caso de ser un UVUS válido se permite continuar con
la ejecución.
// Establecemos conexión con el servidor
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("registra1"); // Enviamos el nombre del alumno
conexion.enviaMensaje(alumno.getUvus());
// Recibimos confirmación del servidor
int resultado = conexion.recibeInt();
o Enviar fichero mediante el método enviaFichero. A continuación se
recibe respuesta del servidor. Tanto si la transferencia se ha realizado
correctamente como si no se mostrará en el cuadro de texto el resultado
obtenido: // Enviamos el fichero
ventana.setTexto2("Enviando su fichero...");
conexion.enviaFichero(alumno.getFichero());
// Recibimos confirmación del servidor
int conf = conexion.recibeInt();
Los mensajes que pueden mostrarse tras la ejecución son:
Su fichero se ha enviado correctamente.
Se ha producido un error enviando el fichero. Por favor vuelva a
intentarlo.
Directorio del fichero no encontrado. Asegúrese de tener
disponible la carpeta PFED con su código y vuelva a intentarlo.
Error al conectar con el servidor.
peticionHerramienta: Es la función que ejecuta la herramienta de corrección en
el servidor. En este caso enviamos al servidor un mensaje con la petición,
iniciamos el Temporizador y esperamos respuesta. // Realizamos la conexión
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("herramienta");
// Iniciamos temporizador
Temporizador temp = new Temporizador(conexion, ventana, 20);
73 – BLOQUE 3. Desarrollo del proyecto – Visión general
Existen distintas respuestas posibles:
o Error de conexión. No se ha podido conectar con el servidor.
o Error de compilación. No se ha podido compilar el programa del alumno
en el servidor.
o Error de ejecución. El programa del alumno no realiza correctamente su
propósito. En este caso adicionalmente se recibe del servidor un fichero
con el informe del error.
o Error de memoria. El programa del alumno no gestiona correctamente la
memoria dinámica.
o Ha vencido el temporizador. En caso de que no se reciba respuesta del
servidor en el tiempo establecido.
o Ejecución satisfactoria. Se coloca un tick en el apartado y se borra si lo
hubiese el informe de error previo.
En la clase ventana hemos visto que utilizamos otras dos clases auxiliares: Temporizador
e Hilo.
La clase Temporizador tiene como atributos un objeto Timer y un objeto TimerTask. Este
último será el encargado de mostrar en la interfaz gráfica un mensaje de error, indicando
que ha vencido el temporizador y cerrando la conexión con el servidor.
El constructor del Temporizador simplemente instancia un nuevo Timer y programa el
TimerTask para una determinada duración establecida como parámetro.
En cuanto a la clase Hilo, implementa la interfaz Runnable de Java y tiene como atributos
un objeto Thread y un entero con la opción elegida. En este caso el método run que se
ejecuta al iniciar el hilo solo tiene dos opciones: Ejecutar el método registraAlumno o el
método peticiónHerramienta:
public void run() {
try {
switch (opcion) {
case 10:
ventana.registraAlumno();
break;
default:
ventana.peticionHerramienta();
break;
}
Estos métodos se ejecutan en paralelo con el proceso principal para poder mostrar la
animación de buffering y no dar la sensación al usuario de que el sistema se ha quedado
bloqueado.
Finalmente se encuentra la clase PrincipalAlumno que es la que se encarga de crear los
objetos Alumno y Comunicación y que inicia la ventana con la interfaz gráfica.
74 – BLOQUE 3. Desarrollo del proyecto – Visión general
Todo ese sistema se empaqueta como un fichero .jar ejecutable y se almacena en una
carpeta junto con las imágenes de la interfaz gráfica. Para hacer más fácil su ejecución
se crea un script que recibe como parámetro el UVUS del alumno y ejecuta el sistema:
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Debe introducir como parámetro su UVUS"
else
java -jar ./system/program.jar $1
fi
Cliente para el examen El cliente para el examen tiene las mismas clases que el cliente para la PFED. Sin
embargo, existen algunas diferencias en los métodos y atributos de algunas clases:
La clase Fichero almacenará el fichero comprimido con el examen en lugar de la
PFED.
La clase Ventana es la que tiene más cambios. El número de botones, así como
su posición y función asociada cambian en esta versión. Los cambios en los
métodos más importantes son:
o En el método registraAlumno la acción requerida al servidor es la de
registrar el examen del alumno en lugar de la PFED.
o Existe un nuevo método que se ejecutará al enviar el fichero con el
examen. Este método es compruebaMake que manda una petición al
servidor para que compruebe si los ficheros críticos para la corrección del
examen no han sido modificados. En caso contrario no permite continuar
con la ejecución.
o El examen de la asignatura se compone de 4 apartados, por lo que en
lugar del método peticionHerramienta se implementa el método
peticionApartado. El procedimiento es similar al anterior. Se establece la
conexión, se envía el apartado a corregir, se inicia el temporizador y se
espera una respuesta. Las posibles respuestas del servidor son similares
que en el caso de peticionHerramienta, solo que en caso de error de
ejecución se almacena un fichero errorApartadoX siendo X el apartado
ejecutado.
En el método run de la clase Hilo se sustituye la opción de peticionHerramienta
por peticionApartado.
Servidor Para el servidor de nuestro sistema utilizaremos las siguientes clases: PrincipalServidor,
Alumno, DataBase, Fichero, Comunicación e Hilo. Algunas de ellas ya estaban presentes
en la parte del cliente pero tienen diferencias sustanciales. La clase Fichero es la única
con el mismo contenido que la versión del lado del cliente.
En el servidor existe una nueva clase, llamada DataBase, que será la encargada de
gestionar la base de datos MongoDB de nuestro sistema. Para esta clase utilizaremos
los drivers de Java disponibles para el manejo de MongoDB. La clase tiene 3 atributos
75 – BLOQUE 3. Desarrollo del proyecto – Visión general
básicos: Un objeto de tipo BasicDBObject que representa un documento JSON, un objeto
de tipo DBCollection con la colección que vamos a utilizar y un objeto DB con nuestra
base de datos.
El constructor de la clase simplemente realiza la conexión con la base de datos utilizando
la IP que se le pasa como parámetro. Así instanciamos los objetos DB y DBCollection:
public DataBase(String IP) throws UnknownHostException {
MongoClient mongoClient = new MongoClient(IP);
// Conecta con la base de datos
db = mongoClient.getDB("fp2");
// Obtiene la colección
coll = db.getCollection("clasefp2");
}
Una vez que ya tenemos la conexión con la base de datos realizada, lo primero es
almacenar en la misma la lista con todos los alumnos. Para ello utilizamos el método
creaLista. Este método recibe como parámetro la ruta al fichero donde se encuentra la
lista de los alumnos.
Para leer este fichero se utiliza un objeto de tipo Scanner con el que leemos el fichero
línea a línea y palabra a palabra para obtener los distintos campos de información. El
fichero de la lista debe seguir el siguiente formato para que el programa funcione
(manteniendo mayúsculas y minúsculas): APELLIDO1 APELLIDO2, NOMBRE uvus.
Lo que hacemos es leer una línea y crear un nuevo Scanner por cada línea leída:
sc2 = new Scanner(new File(ficheroLista));
// Leemos todas las lineas del fichero.
while (sc2.hasNextLine()) {
String apellido = "";
String nombre = "";
String uvus = "";
Scanner s2 = new Scanner(sc2.nextLine());
A continuación leemos palabra a palabra y cambiamos de campo según un criterio:
Los apellidos finalizan al encontrarse una coma.
Las palabras que a continuación estén en mayúsculas pertenecerán al nombre.
La siguiente palabra (en minúsculas) es el UVUS del alumno.
Una vez tenemos todos los campos, los introducimos en la base de datos (si no se
encuentran ya). Para ello creamos un nuevo documento por cada alumno, usando como
identificador el UVUS. Añadimos a ese documento el nombre y los apellidos y finalmente
lo introducimos en la colección si no se había introducido anteriormente:
// Guardamos los datos en la base de datos
doc = new BasicDBObject("_id", uvus);
doc.append("Nombre", nombre);
doc.append("Apellidos", apellido);
// Comprobamos que el usuario no se encuentre ya en
// la base de datos
try {
76 – BLOQUE 3. Desarrollo del proyecto – Visión general
coll.insert(this.doc);
} catch (MongoException e) {
}
Una vez que ya tenemos la lista de alumnos en la base de datos podemos realizar la
comprobación de si un alumno pertenece o no a esa lista. Para ello utilizamos el método
compruebaAlumno, que recibe como parámetro el UVUS del alumno. La comprobación
se realiza de manera muy sencilla, se crea un documento con el identificador del alumno
y se busca en la colección de la base de datos. Si se produce una excepción es que el
documento no se encuentra en la misma. Para buscar un documento utilizamos:
doc = new BasicDBObject("_id", uvus);
coll.find(this.doc).next();
En caso de que el profesor quiera utilizar una base de datos nueva, debe borrar la
antigua. Para eso utilizamos el método borraDatos. En este método simplemente se
define un DBCursor que se encarga de ir recorriendo la colección e ir eliminando cada
uno de los documentos.
Para publicar una nota utilizamos el método publicaNota, que recibe como parámetros
el UVUS del alumno, el apartado en el que almacenar la nota y la nota en sí. Para realizar
este proceso creamos un documento con la nota, buscamos el documento con el
identificador del alumno, y actualizamos el documento del alumno con la nota
correspondiente:
BasicDBObject alumnoDB = new BasicDBObject();
alumnoDB.append("$set", new BasicDBObject().append(apartado, 10));
BasicDBObject searchQuery = new BasicDBObject().append("_id", uvus);
coll.update(searchQuery, alumnoDB);
Finalmente, una vez concluido el examen, será necesario imprimir un fichero con las
notas de los alumnos. Para ello utilizaremos el método imprimeNotas. Se van a imprimir,
por requerimientos del profesorado, dos ficheros de notas: Uno que almacene cada uno
de los documentos JSON de los alumnos en un único documento que los englobe y otro
que almacene los campos de estos documentos en texto plano. El objetivo del primer
fichero impreso es el de almacenar el documento JSON en una variable JavaScript, para
que después sea mostrada en una página web mediante el uso de la herramienta
JQGrid[33]. El segundo fichero podrá leerse como una tabla de Excel.
En este caso el proceso será el inverso que con el método creaLista. Utilizaremos un
objeto PrintWriter para escribir en un fichero y utilizaremos un cursor para ir recorriendo
la base de datos. Por cada documento que apunte el cursor, imprimiremos una línea en
los dos ficheros antes descritos:
DBCursor cursor = coll.find();
while (cursor.hasNext()) {
// Obtenemos los datos del alumno
DBObject alumno = cursor.next();
// Imprimimos el objeto JSON tal cual para el fichero js
writer.println(alumno + ",");
// Extraemos los campos necesarios para el fichero txt
77 – BLOQUE 3. Desarrollo del proyecto – Visión general
String notas = new String(alumno.get("_id")
+"\t"+alumno.get("Nombre")
+"\t"+alumno.get("Apellidos")
+"\t"+alumno.get("PFED")
+"\t"+alumno.get("apartado0")
+"\t"+alumno.get("apartado1")
+"\t"+alumno.get("apartado2")
+"\t"+alumno.get("apartado3"));
// Modificamos los campos a null por espacios en blanco y
// imprimimos en el fichero txt
writer2.println(notas.replaceAll("null", " "));
La clase AlumnoServidor es la que contiene los atributos y funciones necesarios para
procesar las peticiones de los alumnos. Sus atributos son: un objeto String con el UVUS
del alumno, un objeto Comunicación para la conexión con el mismo y un objeto
DataBase para la comunicación con la base de datos.
El constructor simplemente almacena los objetos Comunicación y DataBase obtenidos
como parámetros.
Cuando un alumno se conecte al sistema o decida reenviar su trabajo se debe crear una
carpeta con su UVUS (si no existe previamente) y eliminar el trabajo antes enviado. Esto
se realiza mediante el método creaCarpeta. Este método recibe como parámetro un
entero con la opción a realizar: o elimina el envío anterior de la PFED o del examen. Esto
se realiza mediante llamadas al SO de la siguiente forma:
Runtime runtime;
Process p;
if (opcion == 1) {
runtime = Runtime.getRuntime();
p = runtime.exec("rm -r ./" + uvus + "/PFED/");
p.waitFor();
p = runtime.exec("mkdir " + uvus);
p.waitFor();
Este proceso de gestión de carpetas debe realizarse cuando el alumno invoque el
método para enviar su trabajo. Esta petición la gestiona el método registra, que también
recibe como parámetro la opción a realizar (registro de la PFED o del examen).
El método registra recibe el UVUS del alumno y comprueba en la base de datos si es un
identificador válido o no:
// Recibimos el nombre del alumno
uvus = conexion.recibeString();
// Comprobamos que el alumno está en la lista
res = baseDeDatos.compruebaAlumno(uvus);
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
Si se trata de un usuario válido se crea una carpeta con el método creaCarpeta y se inicia
la recepción del fichero con su trabajo:
78 – BLOQUE 3. Desarrollo del proyecto – Visión general
// Creación de la carpeta del alumno
creaCarpeta(opcion);
// TRANSFERENCIA DE FICHEROS
res = conexion.recibeFichero(this);
Este método recibeFichero de la clase Comunicación varía en cuanto a la versión del
cliente, ya que esta vez no se recibe un fichero simple, si no que se trata de un fichero
comprimido. Por ello, es necesario descomprimirlo una vez ha sido recibido y comprobar
que todo se ha realizado correctamente.
Una vez que ya se han recibido y descomprimido los ficheros del alumno, necesitamos
especificar los métodos para corregir las distintas partes de la evaluación. Para ello
crearemos el método corrigeHerramienta que ejecutará la herramienta de corrección
del Departamento de Ingeniería Telemática y el método corrigeApartado para corregir
cada uno de los apartados del examen.
Comenzamos con el método corrigeHerramienta. Una vez que se ha recibido el UVUS
del usuario que quiere ejecutar este método realizamos las siguientes comprobaciones:
Primero eliminamos el informe de la gestión de memoria dinámica por si
hubiese sido creado de una ejecución anterior.
Comprobamos que el fichero makefile necesario para la ejecución de la
herramienta se encuentra disponible.
Una vez realizado esto ejecutamos la herramienta de corrección:
Runtime runtime;
Process p;
runtime = Runtime.getRuntime();
p = runtime.exec("make -s -C ./" + uvus
+ "/PFED/herramienta/ -f Herramienta");
p.waitFor();
Esto es equivalente a ejecutar la herramienta en un terminal de Linux:
make –s –C ./uvus/PFED/herramienta/ -f Herramienta
La opción –s sirve para que el makefile con los comandos de la herramienta se ejecute
en modo “silencioso”. Solo imprimirá por pantalla la salida estándar y de errores de los
comandos ejecutados por el makefile, sin incluir a los mismos comandos. La opción –C
sitúa al sistema en la carpeta ./uvus/PFED/herramienta (siendo uvus el directorio del
alumno). Por último la opción –f indica que el fichero con el makefile está nombrado
como Herramienta.
De un objeto Process podemos obtener dos flujos de datos. Uno con la salida de errores
usando el método getErrorStream, y otro con la salida estándar del resultado de la
ejecución con el método getInputStream.
Para comprobar que no se han producido errores en la compilación debemos comprobar
que el flujo que nos devuelve el método getErrorStream se encuentra vacío. Si esta
79 – BLOQUE 3. Desarrollo del proyecto – Visión general
comprobación resulta satisfactoria debemos comprobar que la salida por pantalla
también es correcta. Para ello analizamos el flujo de datos obtenido del método
getInputStream y si el resultado no coincide con el esperado de una ejecución
satisfactoria, podemos confirmar que se ha producido un error.
Una vez realizadas estas comprobaciones es necesario analizar un último aspecto antes
de dar una respuesta satisfactoria al alumno. La ejecución de la herramienta genera un
fichero con un informe sobre la gestión de memoria dinámica del trabajo del alumno.
Para que un trabajo se considere válido este informe de estar vacío.
Si todas las comprobaciones han sido superadas satisfactoriamente enviamos
confirmación al alumno y guardamos la nota en la base de datos:
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
baseDeDatos.publicaNota(uvus, "PFED", 10);
En caso contrario se devuelve un mensaje con el código del error. Si el error es de
ejecución (el método getInputStream no devuelve lo esperado al ejecutar la
herramienta) se envía adicionalmente un fichero con la salida del programa obtenida
para que el alumno pueda identificar dónde se ha producido el error.
Si se trata de la corrección del examen hay un aspecto crítico que debemos comprobar
antes de poder corregir ningún apartado. Los ficheros makefile que forman parte del
enunciado y que se ejecutan para saber si un apartado ha sido superado de manera
satisfactoria son susceptibles de ser modificados por los alumnos. Para evitar que un
alumno modifique el contenido de estos ficheros y provoque un comportamiento no
deseado a la hora de corregir un apartado debemos crear un método que compruebe
que estos ficheros permanecen intactos.
Para ello creamos el método compruebaMake. Se trata de un método que realiza una
comprobación sencilla que se ejecuta antes de que el alumno pueda corregir ningún
apartado. Simplemente realizamos un bucle for por los distintos ficheros críticos del
examen y mediante el comando diff de Linux analizamos si existen diferencias entre el
fichero del examen del alumno y el original almacenado en el servidor. Si la
comprobación es insatisfactoria se envía un mensaje de error al alumno.
Por último ya estamos listos para corregir el examen. Este examen se divide en cuatro
apartados, desde el apartado 0 al apartado 3. En el apartado 0 simplemente se requiere
ejecutar la misma herramienta de comprobación que se ha debido de pasar
satisfactoriamente antes de presentar el trabajo personal con la PFED. En los otros 3
apartados se pide realizar modificaciones sobre el código de la PFED para que realice
otras funcionalidades y genere un fichero adicional con el resultado. Para corregir estos
apartados se les proporciona a los alumnos un fichero con la salida que su programa
debe generar como resultado y otro fichero con un makefile que deben ejecutar para
realizar la comparación de manera automática entre el fichero generado por el alumno
y el proporcionado con el examen.
80 – BLOQUE 3. Desarrollo del proyecto – Visión general
Para realizar este proceso en el servidor implementamos el método corrigeApartado.
Este método recibe como parámetro un entero con el apartado que se desea corregir.
Si el apartado elegido es el 0 el procedimiento es el mismo que con el método
corrigeHerramienta. Simplemente hay que modificar la ruta en la que se encuentran los
ficheros objetivo con los que trabajamos.
En el caso de que sea un apartado distinto del 0 el procedimiento también es similar.
Primero se almacena con un nombre diferente el ejecutable resultante del alumno. Este
fichero ejecutable se va a volver a generar por lo que almacenamos el enviado por el
alumno para poder analizarlo ante una posible reclamación.
A continuación ejecutamos el makefile del apartado para realizar la comprobación. El
procedimiento es similar al que hemos especificado anteriormente en
corrigeHerramienta: Comprobamos que no haya errores de compilación y que la salida
sea igual a la esperada. Si todo ha ido bien se almacena en la base de datos la nota de
ese alumno para el apartado corregido y en caso contrario se envía al alumno el informe
con el error obtenido.
Todo este proceso puede analizarse con detalle siguiendo el código comentado
disponible en el Anexo 2.
Un aspecto esencial del sistema es que debe permitir el acceso concurrente de varios
alumnos. Para conseguir esto implementamos la clase Hilo. Se creará un objeto de tipo
Hilo cada vez que se reciba una petición de un alumno. Así podremos tener un hilo de
ejecución por cada petición realizada, asegurando la concurrencia de varios clientes en
el sistema.
Cada hilo almacena en su constructor el código con la petición recibida, la Comunicación
con el alumno y la base de datos con la que conectarse. Esta clase implementa la interfaz
Runnable de Java y dependiendo de la opción recibida llama a una función del sistema
de manera similar a como lo realizamos en el cliente. Las opciones disponibles son las
del registro tanto para la PFED como para el examen, la ejecución de la herramienta y
los distintos apartados del examen, la comprobación de los ficheros críticos del examen
y la de imprimir las notas de la base de datos.
Finalmente nos queda por analizar la clase Principal. Esta contiene el método main y es
la encargada de poner en marcha el servidor. Lo primero que hace es iniciar el socket
que escuchará las conexiones de los alumnos y conectar con la base de datos:
System.out.println("Ejecutando servidor:");
ServerSocket serverSocket = new ServerSocket(8888);
// Conectamos con la base de datos
DataBase mongo= new DataBase("localhost");
A continuación se nos pregunta si queremos crear una base de datos nueva y borrar los
datos de la colección existente o cargar los datos de la misma. En cualquiera de los casos
se llama al método creaLista del objeto DataBase para incluir nuevos alumnos si los
hubiera.
81 – BLOQUE 3. Desarrollo del proyecto – Visión general
Creamos un hilo para la impresión de notas que se quedará a la espera hasta que se
cierre el programa e iniciamos un bucle infinito para la recepción de las peticiones de
los alumnos:
while (true) {
// Comprobamos que tenemos conexión con la base de datos
mongo.compruebaConex();
// Nueva conexión
Comunicacion conexion=new Comunicacion(serverSocket);
// Recibimos función a realizar
opcion = conexion.recibeString();
//Creamos un hilo para la petición del alumno
new Hilo(opcion,conexion, mongo);
Todo el paquete servidor se exporta como un fichero .jar ejecutable junto con el sistema
de ficheros necesario para su ejecución.
Para la representación de notas en la página web, como ya hemos comentado,
utilizaremos la herramienta jqGrid. Esto nos permitirá definir una variable JavaScript con
el documento JSON de los resultados de todos los alumnos. Esta variable se imprimirá
en el fichero fp2.js que luego utilizaremos como fuente para nuestro fichero HTML.
En el fichero HTML definiremos un bloque div en el que se incluirá la tabla con las notas
de los alumnos. Para representar en esa tabla los datos de la variable del documento
JSON llamamos al método jqGrid sobre dicha tabla y le asignamos la configuración
necesaria. Puede ver esta configuración en el bloque 6 Anexo 2.
Control de plagio Una vez que ya se ha concluido el proceso de evaluación pasamos a desarrollar la
herramienta que nos permitirá realizar el control de plagio entre los trabajos
entregados. Es posible que algunos de los trabajos entregados estén formados total o
en parte de otros trabajos. Para comprobar este aspecto desarrollamos una nueva
aplicación basada en el software SIM.
Este sistema se divide en dos clases. Una clase principal con el método main y otra clase
auxiliar con las funciones necesarias para generar el informe de control de plagio. La
clase auxiliar, a la que denominamos Funciones, tendrá 2 atributos: Una lista de String
con los identificadores de todos los alumnos y una lista de apartados en los que se
realizará el control de plagio.
Del proceso de evaluación anterior tenemos disponible en el servidor un directorio las
carpetas del trabajo de los alumnos presentados. Cada una de estas carpetas está
nombrada por el UVUS del alumno por lo que, si queremos leer los identificadores de
los alumnos presentados, basta con leer los nombres de estos directorios. Para ello
creamos el método obtieneAlumnos. Este método obtiene como parámetro el
directorio en el que se encuentran los trabajos y mediante un bucle for obtiene los
nombres de cada una de las carpetas.
82 – BLOQUE 3. Desarrollo del proyecto – Visión general
Una vez que ya tenemos el nombre de todos los alumnos presentados podemos realizar
la evaluación del plagio. Para ello desarrollamos el método compruebaPlagio que recibe
como parámetros el identificador del alumno a evaluar y un objeto PrintWriter que
utilizamos para escribir en el informe final.
La evaluación del alumno se realiza para cada apartado y para cada alumno de la lista.
De modo que para cada caso ejecutamos el siguiente proceso:
p=Runtime.getRuntime().exec("./sim/sim_c.exe -e -p -S -t 30 "
+ "./sim/PFEDExamen/" + alumno +"/Examen/"+apartado.get(i)+"/*.c "
+"/ ./sim/PFEDExamen/"+lista.get(j)+"/Examen/"+apartado.get(i)+"/*.c");
El proceso ejecuta el programa SIM que se encuentra en la ruta ./sim/sim_c.exe. Las
opciones de ejecución son:
-e: Compara uno a uno cada uno de los ficheros con el resto.
-p: El resultado se da en porcentaje de similitud.
-S: Los ficheros de un alumno solo se comparan con los de otro, no entre sí
mismos.
-t 30: Solo se mostrarán porcentajes mayores o igual al 30 %.
Por cada ejecución de este proceso se comparan todos los ficheros de código .c de un
apartado del examen del alumno que estamos evaluando con los de un alumno de la
lista.
Obtenemos el flujo generado por la ejecución del proceso mediante el método
getInputStream. Si este flujo tiene algún contenido es que se han producido
coincidencias entre los ficheros comparados.
Editamos la información que obtenemos de la ejecución del software SIM para
quedarnos solo con la información que nos interesa y la imprimimos en el informe.
El método principal de este sistema simplemente instancia un objeto File con el
directorio de los exámenes de los alumnos, obtiene la lista de alumnos presentados y
por cada uno de ellos realiza el control de plagio:
final File folder = new File("./sim/PFEDExamen");
ArrayList<String> lista = funciones.obtieneAlumnos(folder);
PrintWriter informe=new PrintWriter("informePlagio.txt","UTF-8");
for (int i=0; i<lista.size();i++){
funciones.compruebaPlagio(lista.get(i),informe);
}
83 – BLOQUE 4. Pruebas de ejecución – Servidor
BLOQUE 4. Pruebas de ejecución El detalle de la especificación de cada una de las pruebas realizadas al sistema ya se
realizó siguiendo la metodología de MÉTRICA Versión 3. El objetivo de este bloque es el
de mostrar el resultado de la realización de las pruebas de ejecución del sistema.
El sistema fue probado con éxito durante el examen de la asignatura de Fundamentos
de Programación II realizado el 28 de marzo de 2014 en la Escuela Técnica Superior de
Ingeniería de Sevilla.
Servidor Para probar nuestro sistema lo primero que debemos hacer es ejecutar el programa
servidor en el equipo del profesor responsable:
Con esto ya hemos cargado la lista de alumnos en la base de datos y estamos listos para
recibir conexiones de los alumnos.
Cliente para la PFED A continuación vamos a probar el funcionamiento del corrector de la PFED. Para ello
ejecutamos el script creado usando un UVUS válido:
Si la carpeta con el trabajo no está disponible obtendremos el mensaje de la figura 23
(Izquierda). Si el trabajo se envía correctamente se nos mostrará (figura 23 derecha) un
mensaje de confirmación y las opciones disponibles.
Si el servidor sigue en funcionamiento y pulsamos el botón de “Ejecutar la herramienta”
podemos obtener 3 distintos resultados. En la figuras 24 y 25 vemos los casos posibles:
Figura 24 (Izquierda): el código del alumno tiene errores que no permiten que
se compile.
Figura 24 (Derecha): existen errores en la ejecución de las pruebas y se genera
el fichero errorHerramienta.
Figura 25 (Izquierda): no se gestiona correctamente la memoria.
Figura 25 (Derecha): la ejecución se realiza con éxito.
84 – BLOQUE 4. Pruebas de ejecución – Cliente para la PFED
Figura 23. Fichero no encontrado (Izquierda) – Transferencia correcta (Derecha)
Figura 24. Error de compilación (Izquierda) – Error de ejecución (Derecha)
Figura 25. Error de memoria (Izquierda) – Ejecución satisfactoria (Derecha)
85 – BLOQUE 4. Pruebas de ejecución – Cliente para el examen
Con esto se concluye la evaluación previa al examen. El trabajado del alumno se ha
almacenado en el servidor y si ha pasado las pruebas tendrá aprobada la parte
correspondiente a la entrega de la PFED.
Cliente para el examen A continuación pasamos a la corrección del examen. Como ya hemos dicho se divide en
cuatro apartados (siendo el objetivo del primer apartado volver a ejecutar la
herramienta). El procedimiento para la corrección es el mismo que el anterior, pero en
este caso, si la transferencia de la carpeta con todo el examen del alumno se produce
sin errores, se mostrarán las opciones de la figura 24 (Izquierda). En caso de que el
alumno haya modificado el contenido del enunciado del examen se le mostrará un
mensaje de error como el de la figura 24 (Derecha) y no se le permitirá continuar con la
evaluación.
Figura 24. Transferencia satisfactoria (Izquierda) – Fichero crítico modificado (Derecha)
En caso de que la transferencia haya sido correcta y el alumno pulse el botón de
corrección de algún apartado hay dos posibles respuestas. Si el apartado se completa
satisfactoriamente se muestra un mensaje de confirmación y una imagen de un tick. En
caso contrario, se muestra un mensaje de error y se imprime el fichero errorApartadoX
(siendo X el número del apartado) con el informe del error que se ha producido. Un
ejemplo de examen completado con éxito puede verse en la figura 25.
86 – BLOQUE 4. Pruebas de ejecución – Obtención de notas y detección de plagio
Figura 25. Examen completado con éxito
Obtención de notas y detección de plagio Cada vez que un alumno completa un apartado, el servidor almacena en la base de datos
un 10 en el documento del alumno para el apartado realizado. Una vez finalizada la
evaluación concluimos el proceso del servidor y se imprimen las notas de los alumnos.
En la figura 26 podemos ver cuál es el resultado final.
Tras haber almacenado los trabajos de todos los alumnos en el servidor podemos probar
nuestra herramienta de control de plagio. Esta analizará todos los trabajos y nos
mostrará si ha localizado coincidencias en los trabajos de dos alumnos. Un extracto de
este informe puede verse en la figura 27. En ella vemos como para cada alumno, se
analizan si existen coincidencias en cada uno de los apartados con respecto al trabajo
de otros compañeros. En caso de encontrar similitudes mayores del 30 % nos mostrará
el identificador de los alumnos implicados, cuáles son los ficheros que albergan dicha
similitud y el porcentaje de la misma.
En caso contrario de que el porcentaje de similitud sea menor del 30% no se imprimirá
nada. Se trata de datos de evaluación reales por lo que en las imágenes mostradas se
difuminarán los datos personales de los alumnos para preservar su privacidad.
87 – BLOQUE 4. Pruebas de ejecución – Obtención de notas y detección de plagio
Figura 26. Impresión de notas en formato HTML
Figura 27. Extracto de informe de plagio
88 – BLOQUE 5. Conclusiones y bibliografía – Conclusiones y líneas futuras de trabajo
BLOQUE 5. Conclusiones y bibliografía Conclusiones y líneas futuras de trabajo En este proyecto se ha realizado el desarrollo de una herramienta de asistencia a la
evaluación siguiendo la metodología de MÉTRICA Versión 3. La utilización de esta clase
de herramientas se convierte en un avance notorio en cuanto a optimización del tiempo
y precisión en la corrección.
En el caso de no existir herramientas como las propuestas en este proyecto, las tareas
de corrección y evaluación individual de la gran cantidad de alumnos matriculados
pueden llegar a ser inmanejables para los profesores de la asignatura. Especialmente,
en las asignaturas de programación, donde gracias a estas herramientas, no solo se
agiliza este proceso, sino que también permite evaluar aspectos más avanzados como
el rendimiento o la probabilidad de plagio.
En general, y con el sistema de este proyecto en particular, los estudiantes han
demostrado una buena aceptación del mismo, ya que es muy sencillo de utilizar y
permite conocer de manera inmediata los resultados de su evaluación.
Seguir la metodología de Métrica v3 en el desarrollo garantiza que el sistema pueda ser
reutilizado y mantenido con relativa facilidad, además de asegurar la buena calidad del
mismo.
Este trabajo ha sido desarrollado para cubrir la corrección de la PFED, sin embargo, con
ligeras modificaciones, es posible adaptarlo a otras evaluaciones como, por ejemplo, la
Práctica Final de Programación Orientada a Objetos (PFPOO). Como líneas futuras de
trabajo podemos identificar:
Asegurar el acceso a la base de datos mediante el uso de contraseñas, tanto para
la administración como para el acceso de los alumnos.
Incluir un sistema de registro previo por parte de los alumnos que realizarán el
examen.
Abstraer al alumno de la utilización de la herramienta de comprobación
incluyéndola solo en el servidor.
Publicar de manera automática las notas de los alumnos en un servidor web una
vez finalizado el examen.
Registrar el acceso y las modificaciones de los alumnos en su trabajo para realizar
comprobaciones ante una posible reclamación.
Incluir un histórico con las distintas versiones del trabajo que envían los alumnos.
Aumentar la flexibilidad del sistema para que sea capaz de corregir también la
Práctica Final de Programación Orientada a Objetos.
Incluir el proceso de control de plagio en el sistema principal para informar a los
alumnos en tiempo real de su resultado.
89 – BLOQUE 5. Conclusiones y bibliografía – Bibliografía
Bibliografía [1] Ministerio de Administraciones Públicas. Métrica v.3.
http://administracionelectronica.gob.es/pae_Home/pae_Documentacion/pae_Metod
olog/pae_Metrica_v3.html
[2] JISC. Effective Practice with e-Assessment. (2007). Introduction (p. 6).
http://www.jisc.ac.uk/media/documents/themes/elearning/effpraceassess.pdf
[3] Andrew Boyle, Dougal Hutchison. (2009). Sophisticated tasks in e-assessment:
What are they and what are their benefits?, Assessment & Evaluation in Higher
Education.
[4] Osuji, U. S. A. (2012). The Use of e-Assessments in the Nigerian Higher Education
System. Turkish Online Journal of Distance Education.
[5] Universidad de Sevilla. Qué es la Enseñanza Virtual.
https://ev.us.es:8443/portalev/menu/que_es_ensenanza_virtual.jsp
[6] A.J. Sierra, T. Ariza, F. J. Fernandez. (2012) Establishment EHEA for
telecommunication technologies engineering degree Global Engineering Education
Conference (EDUCON). (pp 1-6)
[7] A. J. Sierra, T. Ariza, F. J. Fernández. (2013) PBL in Programming Subjects at
Engineering. Bulletin of the IEEE Technical Committee on Learning Technology. Volume
15, Number 2. (pp 1-4)
[8] A. J. Sierra, T. Ariza, F. J. Fernandez, G. Madinabeitia. (2012). TVSP: A Tool for
Validation Software Projects in programming labs Global Engineering Education
Conference (EDUCON)
[9] A. J. Sierra, T. Ariza, F. J. Fernandez, G. Madinabeitia. (2012). Tool for Validation
Software Projects in Programming Labs, International Journal of Engineering Pedagogy
(iJEP), Vol 2, No 2.
[10] Leo Ferres. (2010). Memory management in C: The heap and the stack.
Department of Computer Science. Universidad de Concepción.
[11] Sergio Bellido Sánchez. (2012). Aplicación para el e-Assessment en la asignatura
Programación Orientada a Objetos. E-Assessment mediante Bases de Datos NoSQL (pp
73-95).
[12] Alexandru Boicea, Florin Radulescu, Laura Ioana Agapin. (2012). MongoDB vs
Oracle - database comparison. Third International Conference on Emerging Intelligent
Data and Web Technologies.
[13] Sergio Bellido Sánchez. (2012). Test de Rendimiento. E-Assessment mediante
Bases de Datos NoSQL (pp 73-95).
90 – BLOQUE 5. Conclusiones y bibliografía – Bibliografía
[14] MongoDB Inc. Agile and Scalable. http://www.mongodb.org/
[15] Introducción a JSON. http://www.json.org/json-es.html
[16] MongoDB Inc. Replication. http://docs.mongodb.org/manual/replication/
[17] MongoDB Inc. Sharding. http://docs.mongodb.org/manual/sharding/
[18] MongoDB Inc. Manual. http://docs.mongodb.org/manual/
[19] MongoDB Inc. Introduction to MongoDB.
http://docs.mongodb.org/manual/core/introduction/
[20] Jurriaan Hage, Peter Rademaker, Nikè van Vugt. (2010). A comparison of
plagiarism detection tools (pp 3-21).
[21] The software and text similarity tester SIM.
http://dickgrune.com/Programs/similarity_tester/
[22] Manual SIM. http://dickgrune.com/Programs/similarity_tester/sim.pdf
[23] Ministerio de Administraciones Públicas. Aportaciones de MÉTRICA Versión 3.
Introducción. (p 2).
[24] Unix Command: diff. http://linux.about.com/library/cmd/blcmdl_diff.htm
[25] Microsoft. Capitalization Styles. http://msdn.microsoft.com/en-
us/library/x2dbyw72(v=vs.71).aspx
[26] MongoDB Inc. Java Language Center.
http://docs.mongodb.org/ecosystem/drivers/java/
[27] MongoDB Inc. Installation Guide.
http://docs.mongodb.org/manual/administration/install-on-linux/
[28] Ministerio de Administraciones Públicas. Estudio de Viabilidad del Sistema
(Proceso EVS).
http://administracionelectronica.gob.es/pae_Home/dms/pae_Home/documentos/Doc
umentacion/Metodologias-y-
guias/Metricav3/METRICA_V3_Estudio_de_Viabilidad_del_Sistema.pdf
[29] Ministerio de Administraciones Públicas. Análisis del Sistema de Información
(Proceso ASI).
http://administracionelectronica.gob.es/pae_Home/dms/pae_Home/documentos/Doc
umentacion/Metodologias-y-
guias/Metricav3/METRICA_V3_Analisis_del_Sistema_de_Informacion.pdf
[30] Ministerio de Administraciones Públicas. Diseño del Sistema de Información
(Proceso DSI).
http://administracionelectronica.gob.es/pae_Home/dms/pae_Home/documentos/Doc
91 – BLOQUE 5. Conclusiones y bibliografía – Bibliografía
umentacion/Metodologias-y-
guias/Metricav3/METRICA_V3_Diseno_del_Sistema_de_Informacion.pdf
[31] Ministerio de Administraciones Públicas. Construcción del Sistema de Información
(Proceso CSI).
http://administracionelectronica.gob.es/pae_Home/dms/pae_Home/documentos/Doc
umentacion/Metodologias-y-
guias/Metricav3/METRICA_V3_Construccion_del_Sistema_de_Informacion.pdf
[32] Ministerio de Administraciones Públicas. Implantación y Aceptación del Sistema
(Proceso IAS).
http://administracionelectronica.gob.es/pae_Home/dms/pae_Home/documentos/Doc
umentacion/Metodologias-y-
guias/Metricav3/METRICA_V3_Implantacion_y_Aceptacion_del_Sistema.pdf
[33] jQuery Grid Plugin – jqGrid. http://www.trirand.com/blog/
92 – BLOQUE 5. Conclusiones y bibliografía – Resumen
Resumen
Este proyecto trata sobre la realización de una herramienta de asistencia a la evaluación
o e-assesment siguiendo la metodología de Métrica v3. Para ello se ha realizado un
sistema que corrige de manera automática el trabajo de programación de los alumnos
de la asignatura de Fundamentos de Programación II de la Escuela Técnica Superior de
Ingeniería de Sevilla. Posteriormente, realiza un proceso de control para detectar
posibles plagios en el trabajo de los alumnos.
El proyecto se divide en 5 bloques. Un primer bloque de introducción, un segundo
bloque sobre el estado del arte, un tercer bloque en el que se aplica la metodología de
Métrica al desarrollo del proyecto, un cuarto bloque en el que se detalla la generación
de código, el resultado obtenido, las conclusiones y líneas futuras y, finalmente, un
bloque con los anexos del proyecto.
En el estado del arte se analizan tres campos diferentes. El primer campo está dedicado
a las herramientas de asistencia a la evaluación disponibles en la actualidad. Analizamos
la plataforma de Enseñanza Virtual, la herramienta de ejecución de pruebas desarrollada
por el Departamento de Ingeniería Telemática, y la aproximación realizada previamente
por un antiguo alumno para un proyecto de corrección automática similar al que nos
ocupa.
En el segundo campo tratamos las bases de datos no relacionales. Nuestro sistema se
apoya en una base de datos de este tipo para el almacenamiento persistente de los
datos de los alumnos. Vemos las ventajas que nos ofrecen y estudiamos, en particular,
el gestor de base de datos MongoDB.
En el tercer campo analizamos distintas herramientas disponibles para la detección de
plagios en documentos escritos y ficheros de código. Describimos las posibilidades que
nos ofrecen y detallamos las particularidades del software SIM que utilizaremos en
nuestro sistema.
El siguiente bloque trata sobre la aplicación de la metodología de Métrica v3 a nuestro
proyecto. Hacemos una introducción a Métrica y analizamos los distintos procesos que
componen la metodología. A continuación realizamos la aplicamos del proceso de
desarrollo. Este proceso se compone de un estudio de la viabilidad del sistema, un
análisis del sistema desarrollado y el diseño, y la construcción e implementación del
mismo, incluyendo el plan de pruebas establecido.
En el cuarto bloque se detalla el proceso de codificación del proyecto. Se analizan cada
uno de los bloques y clases del sistema basándonos en el código desarrollado. A
continuación se muestra el resultado de las pruebas de ejecución. Finalmente se
detallan las conclusiones obtenidas y las líneas futuras de trabajo.
El último bloque está dedicado a mostrar los manuales ofrecidos a los profesores y
alumnos de la asignatura para la utilización de cada una de las partes del sistema y la
última versión del código utilizado.
93 – BLOQUE 6. Anexos – Anexo 1. Manuales de usuario
BLOQUE 6. Anexos Anexo 1. Manuales de usuario
Instrucciones corrector PFED Asegúrese de que su trabajo pasa las pruebas realizadas por la herramienta
proporcionada.
Cree la carpeta PFED (IMPORTANTE: Mantener las mayúsculas). Guarde en ella
tanto su código cómo la herramienta utilizada (IMPORTANTE: No modifique
ningún elemento dentro de la carpeta herramienta).
Descargue de la plataforma de Enseñanza Virtual el fichero CorrectorPFED.zip y
descomprímalo.
Copie la carpeta PFED con su código dentro de la carpeta CorrectorPFED. Debe
de tener una estructura de archivos similar a esta:
Sitúese dentro de la carpeta CorrectorPFED y ejecute el script proporcionado
usando pasándole como argumento su UVUS. Para ello escriba en el terminal la
siguiente línea (sustituyendo miuvus por su UVUS personal):
./ejecucion.sh miuvus
Si todo ha ido bien se le mostrará la siguiente pantalla:
HerramientaMake
include
…
herramienta
Código fuente
system
PFED CorrectorPFED
ejecucion.sh
94 – BLOQUE 6. Anexos – Anexo 1. Manuales de usuario
Pulse el botón “Ejecutar herramienta” para utilizar la aplicación. Si el resultado
es positivo se mostrará por pantalla un mensaje de confirmación. En caso
contrario se informará del error y se generara el archivo errorHerramienta
con la salida de la herramienta:
Caso éxito Caso error
Se deja a criterio del profesor la elaboración de las instrucciones de la herramienta para
el examen.
95 – BLOQUE 6. Anexos – Anexo 1. Manuales de usuario
Instrucciones para la instalación y ejecución del servidor
1. Descargue e instale el servidor MongoDB en la máquina servidor. Puede seguir
los pasos descritos en el siguiente enlace:
http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/
2. Asegúrese de que tiene el servidor MongoDB en ejecución.
3. Descomprima el fichero ServidorPFED.
4. Sustituya el fichero listafp2.txt con la lista de los alumnos del curso
correspondiente. El formato de la lista debe ser el siguiente (manteniendo
mayúsculas y minúsculas, el grupo es opcional):
APPELLIDOS, NOMBRE uvus [Grupo]
5. Copie en este directorio la carpeta Examen con el examen correspondiente, en
cuyo interior deben estar los directorios Apartado0, Apartado1, Apartado2,
Apartado3.
6. Es importante mantener los nombres de los ficheros que se encuentran tanto
en estos apartados como en la herramienta, es decir, para ejecutar el apartado
0 se escribiría:
#Apartado0/herramienta> make –f HerramientaMake
Y para el resto de apartados:
#Apartado1> make –B –f examenAptdo1
7. Ejecute el programa servidor:
java –jar servidor.jar
8. Siga los pasos descritos. Cree una nueva base de datos si es la primera vez que
lo utiliza o se trata de una nueva promoción.
9. Una vez finalizado el periodo de evaluación, pulse intro en el terminal en el que
se esté ejecutando el servidor. Se generarán los ficheros notas/notas.html y
notas.txt con las notas de todos los alumnos y se cerrará el programa.
Instrucciones para el sistema de control de plagio Solo válido para sistema operativo Windows.
1. Copie en la carpeta sim/PFEDExamen/ las carpetas de los examenes de los
alumnos.
2. Ejecute el fichero controlPlagio.jar en un terminal:
java -jar controlPlagio.jar
3. Se generará un fichero informePlagio.txt con la información necesaria. En este
informe se detalla el porcentaje de similitud (en caso de que sea mayor de un
30%) entre los apartados del examen de cada uno de los alumnos con respecto
a todos sus compañeros.
96 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Anexo 2. Código fuente
Corrector PFED
Principal.java /**
* Trabajo final de grado
* Programa principal para el equipo del alumno
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.io.IOException;
public class Principal {
/**
* Método main. El usuario introduce como parámetros su identificador y el
* fichero comprimido con el código de su trabajo. Primero se realiza un
* registro por parte del alumno en el sistema. A partir de ahí es el alumno
* el que decide que opción tomar en la interfaz gráfica.
*
* @param args
* @throws ClassNotFoundException
* @throws InterruptedException
* @see Alumno
* @see Ventana
*/
public static void main(String[] args) throws IOException,
ClassNotFoundException, InterruptedException {
if (args.length < 1)
System.out.println("Debe introducir como argumentos su UVUS");
else {
// IP despacho 193.147.162.136
Alumno alumno = new Alumno(args[0]);
Comunicacion conexion= new Comunicacion("193.147.162.136");
//Creamos la interfaz gráfica
Ventana ventana = new Ventana(alumno, conexion);
ventana.setTexto1("Bienvenido, su fichero se está enviando:");
ventana.setVisible(true);
ventana.setResizable(false);
//Iniciamos buffering
ventana.setBuff();
//Iniciamos el registro
int res = ventana.registraAlumno();
ventana.delBuff();
if (res == 1) {
//Si todo ha ido bien, mostramos los botones de funcionalidad
ventana.addButtons(alumno);
}
}
}
}
97 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Alumno.java /**
* Trabajo final de grado
* Clase Alumno. Contiene los atributos y los métodos necesarios para la
gestión de los datos de un alumno.
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.io.IOException;
public class Alumno {
private String uvus;
private Fichero fichero;
/**
* Constructor de la clase. Guarda su uvus y el fichero asignado al alumno.
*
* @param uvus
* UVUS del alumno
* @param rutaFichero
* ruta en la que se localiza el fichero a enviar
* @throws InterruptedException
* @throws IOException
*/
public Alumno(String uvus) throws IOException, InterruptedException {
// Guardamos las variables
this.uvus = uvus;
fichero = new Fichero("./PFED");
}
/**
* Función que devuelve el UVUS del alumno
*
* @return UVUS
*/
public String getUvus() {
return uvus;
}
/**
* Función que devuelve el fichero del alumno.
*
* @return Fichero
* @throws InterruptedException
* @throws IOException
*/
public Fichero getFichero() throws IOException, InterruptedException {
fichero = new Fichero("./PFED");
return fichero;
}
}
98 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Comunicacion.java /**
* Trabajo final de grado
* Clase Comunicación. Contiene los atributos y los métodos necesarios para la
gestión de la comunicación cliente-servidor.
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Comunicacion {
private String ipServer;
private Socket socket;
/**
* Constructor de la clase. Guardamos la IP del servidor.
*
* @param IP
* IP del servidor
*/
public Comunicacion (String IP){
ipServer=IP;
}
/**
* Función que establece la conexión con el servidor y guarda el socket de
* la misma.
*
* @throws UnknownHostException
* @throws IOException
*/
public void estableceConex () throws UnknownHostException, IOException{
// Realizamos la conexión
socket = new Socket(ipServer, 8888);
}
/**
* Funcion que cierra la conexión con el servidor.
*
* @throws IOException
*/
public void cierraConex () throws IOException{
socket.close();
}
/**
* Función que recibe un objeto tipo String.
*
* @return devuelve el objeto String recibido
* @throws IOException
99 – BLOQUE 6. Anexos – Anexo 2. Código fuente
* @throws ClassNotFoundException
*/
public String recibeString() throws IOException,
ClassNotFoundException {
InputStream istream = socket.getInputStream();
ObjectInput in = new ObjectInputStream(istream);
return (String) in.readObject();
}
/**
* Función que recibe un objeto tipo entero.
*
* @return devuelve el objeto entero recibido
* @throws IOException
*/
public int recibeInt() throws IOException {
DataInputStream istream = new DataInputStream(socket.getInputStream());
return istream.readInt();
}
/**
* Función que envía un objeto de tipo entero.
*
* @param mensaje
* entero a enviar
* @throws IOException
*/
public void enviaMensaje(int mensaje) throws IOException {
DataOutputStream ostream = new DataOutputStream(
socket.getOutputStream());
ostream.writeInt(mensaje);
ostream.flush();
}
/**
* Función que envía un objeto de tipo String.
*
* @param mensaje
* String a enviar
* @throws IOException
*/
public void enviaMensaje( String mensaje) throws IOException {
OutputStream ostream = socket.getOutputStream();
ObjectOutput s = new ObjectOutputStream(ostream);
s.writeObject(mensaje);
s.flush();
}
/**
* Función que envia un fichero. Primero se manda el tamaño del fichero y
* luego el fichero en si.
*
* @param fichero
* fichero a enviar
* @see Fichero
* @throws IOException
*/
public void enviaFichero(Fichero fichero) throws IOException {
// Enviamos el tamaño del fichero
OutputStream ostream = socket.getOutputStream();
ObjectOutputStream s = new ObjectOutputStream(ostream);
s.writeObject(fichero.getTam());
s.flush();
// Enviamos el fichero
byte[] bytearray = fichero.getByteArray();
100 – BLOQUE 6. Anexos – Anexo 2. Código fuente
FileInputStream fin = new FileInputStream(fichero.getFichero());
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray, 0, bytearray.length);
OutputStream os = socket.getOutputStream();
os.write(bytearray, 0, bytearray.length);
os.flush();
bin.close();
}
/**
* Función que recibe un fichero. Primero se recibe el tamaño del fichero y
* luego el fichero en si.
*
* @param nombreFichero
* nombre con el que guardaremos el fichero
* @throws IOException
*/
public void recibeFichero(String nombreFichero) throws IOException{
// Recibimos el tamaño del fichero
int filesize = recibeInt();
// Recibimos el fichero
int bytesRead = 0; // Bytes leidos en una iteración del bucle
int currentTot = 0; // Bytes leidos hasta el momento
byte[] bytearray = new byte[filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("./"+nombreFichero);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray, 0, bytearray.length);
currentTot = bytesRead;
while (bytesRead > -1 && currentTot < filesize) {
bytesRead = is.read(bytearray, currentTot,
(bytearray.length - currentTot));
if (bytesRead >= 0)
currentTot += bytesRead;
}
bos.write(bytearray, 0, currentTot);
bos.flush();
}
}
101 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Ventana.java /**
* Trabajo final de grado
* Clase ventana. Interfaz gráfica del programa utilizando la biblioteca
Swing.
* En esta interfaz se muestra una etiqueta que nos informa del último paso
realizado y
* un texto que nos informa sobre el resultado obtenido. Además se muestran
diferentes
* botones para la realización de las distintas funciones y una animación de
buffering
* mientras el sistema realiza las distintas funciones.
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Ventana extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel vtexto1;
private JTextArea vtexto2;
private JPanel panel;
private JButton reenviarButton;
private JButton apartado0;
private JButton quitButton;
private ImageIcon img;
private JLabel imagen0;
private JLabel buff;
Ventana ventana = this;
// Opcion elegida
private int opcion;
// Alumno utilizado
private Alumno alumno;
// Conexion utilizada
private Comunicacion conexion;
/**
* Contructor de la clase. Se crea un nuevo panel y se establece el título y
* las dimensiones utilizadas, así como el resto de características básicas.
*
* @param alumnoRec
* Alumno que ejecuta la interfaz gráfica
* @param conexionRec
* Conexión extablecida con el servidor
* @throws IOException
*/
102 – BLOQUE 6. Anexos – Anexo 2. Código fuente
public Ventana(Alumno alumnoRec, Comunicacion conexionRec)
throws IOException {
// Guardamos referencia a alumno
alumno = alumnoRec;
// Guardamos referncia a la conexion
conexion = conexionRec;
// Creamos el panel
panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(null);
// Introducimos el título
setTitle("Herramienta PFED");
// Establecemos las dimensiones del panel.
setSize(500, 420);
// Inicializamos las imágenes y el texto.
img = new ImageIcon("system/images/tick.png");
imagen0 = new JLabel(img);
vtexto1 = new JLabel("");
vtexto2 = new JTextArea("");
// Buffering
buff = new JLabel();
ImageIcon imageIcon = new ImageIcon("system/images/buff.gif");
buff.setIcon(imageIcon);
imageIcon.setImageObserver(buff);
buff.setBounds(170, 100, 200, 100);
panel.add(buff);
buff.setVisible(false);
// Establecemos la posición de la ventana y la función asociada a
// cerrarla.
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
/**
* Función que establece el texto de la etiqueta utilizada. Borra el texto
* que estuviese escrito anteriormente y lo sustituyo por el nuevo.
*
* @param texto
* texto a introducir
*/
public void setTexto1(String texto) {
panel.remove(vtexto1);
vtexto1 = new JLabel(texto);
vtexto1.setBounds(10, 10, 200, 40);
vtexto1.setSize(500, 100);
panel.add(vtexto1);
panel.revalidate();
panel.repaint();
}
/**
* Función que establece el texto del campo de texto. Borra el texto que
* estuviese escrito anteriormente y lo sustituyo por el nuevo.
*
* @param texto
* texto a introducir
*/
public void setTexto2(String texto) {
panel.remove(vtexto2);
vtexto2 = new JTextArea(texto);
vtexto2.setBounds(10, 100, 200, 40);
vtexto2.setSize(480, 100);
vtexto2.setLineWrap(true);
vtexto2.setWrapStyleWord(true);
vtexto2.setBorder(BorderFactory.createEmptyBorder(10, 10, 15, 10));
103 – BLOQUE 6. Anexos – Anexo 2. Código fuente
vtexto2.setVisible(true);
panel.add(vtexto2);
panel.revalidate();
panel.repaint();
}
/**
* Función que añade los botones y les asocia las distintas funciones del
* programa.
*
* @throws InterruptedException
* @throws IOException
*/
public void addButtons(final Alumno alumno) throws IOException,
InterruptedException {
// Botón para reenviar el código
reenviarButton = new JButton("Reenviar código");
reenviarButton.setBounds(20, 250, 200, 40);
// Botón para realizar el Apartado0
apartado0 = new JButton("Ejecutar herramienta");
apartado0.setBounds(260, 250, 200, 40);
// Botón para cerrar el programa
quitButton = new JButton("Salir");
quitButton.setBounds(20, 320, 440, 40);
// Función para el boton de cerrar
quitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
// Función para el boton de reenviar
reenviarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Reenviando código:");
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 10);
}
});
// Función para el boton de apartado0
apartado0.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Ejecutando Herramienta:");
ventana.setTexto2("");
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 0);
}
});
panel.add(quitButton);
panel.add(reenviarButton);
panel.add(apartado0);
panel.revalidate();
panel.repaint();
}
104 – BLOQUE 6. Anexos – Anexo 2. Código fuente
public int getOp() {
return opcion;
}
/**
* Función que elimina los botones para realizar los distintos apartados.
*
* @param ventana
* Ventana de la que se eliminan los botones
*/
public void delButtons(Ventana ventana) {
if (ventana.apartado0 != null) {
panel.remove(ventana.apartado0);
}
panel.revalidate();
panel.repaint();
}
/**
* Función que muestra una imagen de confirmación.
*
* @param apartado
* apartado para el que se debe mostrar el tick
*/
public void tick() {
imagen0.setBounds(380, 250, 200, 40);
panel.add(imagen0);
panel.revalidate();
panel.repaint();
}
/**
* Función que elimina las imágenes de confirmación.
*/
public void delTick() {
panel.remove(imagen0);
panel.revalidate();
panel.repaint();
}
public JPanel getPanel() {
return panel;
}
/**
* Función que muestra la animación de buffering.
*
* @throws InterruptedException
*/
public void setBuff() {
ventana.setTexto2("");
buff.setVisible(true);
}
/**
* Función que elimina la animación de buffering.
*/
public void delBuff() {
buff.setVisible(false);
}
/* A partir de ahora se definen las funciones asociadas a los distintos
botones */
105 – BLOQUE 6. Anexos – Anexo 2. Código fuente
/**
* Función que gestiona el registro de un usuario en el sistema. Realiza las
* siguientes funciones:
* - Envía el UVUS del alumno.
* - Envía el fichero del alumno.
* - Recibe la confirmación del servidor y muestra en una ventana el
* resultado del proceso.
*
* @throws UnknownHostException
* @throws IOException
* @throws InterruptedException
*/
public int registraAlumno() throws IOException, ClassNotFoundException,
InterruptedException {
int res = 0;
try {
// Establecemos conexion con el servidor
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("registra1");
// Enviamos el nombre del alumno
conexion.enviaMensaje(alumno.getUvus());
// Recibimos confirmación del servidor
int resultado = conexion.recibeInt();
if (resultado == 1) {
ventana.setTexto2("Nombre de usuario no valido. Por favor, compruebe
que ha introducido "
+ "un nombre de usuario válido y vuelva a intentarlo.");
} else if (resultado == 2) {
// Iniciamos la transferencia
try {
// Enviamos el fichero
ventana.setTexto2("Enviando su fichero...");
conexion.enviaFichero(alumno.getFichero());
// Recibimos confirmación del servidor
int conf = conexion.recibeInt();
if (conf == 1) {
ventana.setTexto2("Su fichero se ha enviado correctamente.");
conexion.cierraConex();
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("rm ./PFED.zip ");
p.waitFor();
// Continuamos la ejecución
ventana.delTick();
res = 1;
} else {
conexion.cierraConex();
ventana.setTexto2("Se ha producido un error enviando el
fichero. Por favor, vuelva a intentarlo.");
}
} catch (FileNotFoundException e) {
conexion.cierraConex();
ventana.setTexto2("Directorio no encontrado. Asegúrese de tiene
disponible la carpeta PFED con su código y la herramienta en el directorio
actual.");
}
}else {
conexion.cierraConex();
106 – BLOQUE 6. Anexos – Anexo 2. Código fuente
ventana.setTexto2("Error al conectar con la base de datos del
servidor.");
}
} catch (ConnectException e) {
ventana.setTexto2("Error al conectar con el servidor. Por favor,
cierre el programa y vuelva a intentarlo"
+ ", si el problema persiste pónganse en contacto con el
profesor.");
}
return res;
}
/**
* Función que gestiona la petición de realizacion de la herramienta
*
* @throws UnknownHostException
* @throws IOException
* @throws InterruptedException
*/
public void peticionHerramienta() throws UnknownHostException, IOException,
InterruptedException {
// Realizamos la conexión
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("herramienta");
// Iniciamos temporizador
Temporizador temp = new Temporizador(conexion, ventana, 20);
// Enviamos el nombre del alumno
conexion.enviaMensaje(alumno.getUvus());
// Recibimos confirmación del servidor
try {
int resultado = conexion.recibeInt();
if (resultado == 1) {
conexion.recibeFichero("./errorHerramienta");
ventana.setTexto2("La Herramienta no se ha ejecutado con éxito"
+ ". Por favor, asegurese de que pasa las pruebas de manera
local y vuelva a intentarlo.\n"
+ "Se ha generado el fichero errorHerramienta"
+ " con la salida obtenida.");
} else if (resultado == 2) {
ventana.setTexto2("Error en la gestión de memoria. Para más
información ejecute la herramienta de manera local y observe los ficheros" +
"del directorio herramienta/pruebas/MemoryRep");
} else if (resultado== 3) {
ventana.setTexto2("Ejecución de la herramienta completada
satisfactoriamente");
ventana.tick();
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("rm errorHerramienta");
p.waitFor();
} else if (resultado==10){
ventana.setTexto2("Error de compilación. Asegúrese de pasar las
pruebas de manera local y vuelva a intentarlo.");
} else {
ventana.setTexto2("Error al conectar con el servidor. Vuelva a
intentarlo");
}
} catch (SocketException e) {
}
// Cancelamos temporizador
temp.cancelar();
}
}
107 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Hilo.java /**
* Trabajo final de grado
* Clase Hilo. Genera un nuevo hilo que realiza una función básica del
sistema.
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.io.IOException;
public class Hilo implements Runnable {
private Thread t;
private int opcion;
private Ventana ventana;
/**
* Constructor de la clase. Recibe como parámetros los elementos necesarios
* para la gestión de las peticiones.
*
* @param ventanaRec
* interfaz gráfica utilizada
* @param opcionRec
* opción elegida por el alumno (registo o ejecución de un
* apartado)
*/
Hilo(Ventana ventanaRec, int opcionRec) {
t = new Thread(this);
opcion = opcionRec;
ventana = ventanaRec;
t.start();
}
/**
* Función que realiza cada uno de los hilos creados. Obtiene la opción a
* realizar y llama a la función correspondiente.
*/
public void run() {
try {
switch (opcion) {
case 10:
ventana.registraAlumno();
break;
default:
ventana.peticionHerramienta();
break;
}
ventana.delBuff();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
108 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Fichero.java /**
* Trabajo final de grado
* Clase fichero. Contiene los atributos y los métodos necesarios para la
transferencia de un fichero.
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.io.File;
import java.io.IOException;
public class Fichero {
private File fichero;
private byte[] bytearray;
int size;
/**
* Contructor de la clase. Almacena el fichero, su tamaño y la secuencia de
* bytes que lo componen.
*
* @param rutaFichero
* ruta del fichero a utilizar
* @throws IOException
* @throws InterruptedException
*/
public Fichero(String rutaFichero) throws IOException, InterruptedException
{
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("zip -r PFED.zip "+rutaFichero);
p.waitFor();
fichero = new File("./PFED.zip");
size = (int) fichero.length();
bytearray = new byte[size];
}
/**
* Constructor por defecto
*/
public Fichero() {
}
/**
* Función que devuelve el fichero utilizado.
*
* @return fichero utilizado
*/
public File getFichero() {
return this.fichero;
}
/**
* Función que devuelve la secuencia de bytes del fichero.
*
* @return cadena de bytes del fichero
*/
public byte[] getByteArray() {
return this.bytearray;
}
/**
* Función que devuelve el tamaño del fichero.
*
109 – BLOQUE 6. Anexos – Anexo 2. Código fuente
* @return tamaño del fichero
*/
public int getTam() {
return this.size;
}
}
110 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Temporizador.java /**
* Trabajo final de grado
* Clase Temporizador. Asegura que el sistema no se quede bloqueado
* en caso de producirse un bucle en la gestión del código del alumno.
*
* @author Andrés Martínez Gotor
*/
package alumnoTrabajo;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class Temporizador {
private Timer temp;
private Ventana ventana;
private Comunicacion conexion;
private TimerTask venceTemp = new TimerTask() {
@Override
public void run() {
ventana.setTexto2("Ha vencido el temporizador. Posible bucle infinito
o sobrecarga del servidor. "
+ "Asegurese del correcto funcionamiento de su programa y vuelva
a intentarlo");
ventana.delBuff();
try {
conexion.cierraConex();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
/**
* Constructor del temporizador. Programa el evento de vencimiento del
* temporizador. Este evento cierra la conexión establecida y muestra un
* mensaje de error.
*
* @param conexionRec
* conexión establecida cliente-servidor
* @param ventanaRec
* interfaz gráfica utilizada
* @param segundos
* segundos hasta vencer el temporizador
*/
public Temporizador(Comunicacion conexionRec, Ventana ventanaRec,
int segundos) {
ventana = ventanaRec;
conexion = conexionRec;
temp = new Timer();
temp.schedule(venceTemp, segundos * 1000);
}
/**
* Función que cancela el temporizador.
*/
public void cancelar() {
temp.cancel();
}
}
111 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Corrector Examen
Principal.java /**
* Trabajo final de grado
* Programa principal para el equipo del alumno
*
* @author Andrés Martínez Gotor
*/
package alumnoExamen;
import java.io.IOException;
public class Principal {
/**
* Método main. El usuario introduce como parámetros su identificador y el
* fichero comprimido con el código de su trabajo. Primero se realiza un
* registro por parte del alumno en el sistema. A partir de ahí es el alumno
* el que decide que opción tomar en la interfaz gráfica.
*
* @param args
* @throws ClassNotFoundException
* @throws InterruptedException
* @see Alumno
* @see Ventana
*/
public static void main(String[] args) throws IOException,
ClassNotFoundException, InterruptedException {
if (args.length != 1)
System.out.println("Debe introducir como argumento su UVUS");
else {
// IP despacho 193.147.162.136
Alumno alumno = new Alumno(args[0]);
Comunicacion conexion= new Comunicacion("193.147.162.136");
//Creamos la interfaz gráfica
Ventana ventana = new Ventana(alumno, conexion);
ventana.setTexto1("Bienvenido, su fichero se está enviando:");
ventana.setVisible(true);
ventana.setResizable(false);
//Iniciamos buffering
ventana.setBuff();
//Iniciamos el registro
int res = ventana.registraAlumno();
ventana.delBuff();
if (res == 1) {
//Si todo ha ido bien, mostramos los botones de funcionalidad
ventana.addButtons();
}
}
}
}
112 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Alumno.java /**
* Trabajo final de grado
* Clase Alumno. Contiene los atributos y los métodos necesarios para la
gestión de los datos de un alumno.
*
* @author Andrés Martínez Gotor
*/
package alumnoExamen;
import java.io.IOException;
import alumnoExamen.Fichero;
public class Alumno {
private String uvus;
private Fichero fichero;
/**
* Constructor de la clase. Guarda su uvus y el fichero asignado al alumno.
*
* @param uvus
* UVUS del alumno
* @param rutaFichero
* ruta en la que se localiza el fichero a enviar
* @throws InterruptedException
* @throws IOException
*/
public Alumno(String uvus) throws IOException, InterruptedException {
// Guardamos las variables
this.uvus = uvus;
fichero = new Fichero("./Examen");
}
/**
* Función que devuelve el UVUS del alumno
*
* @return UVUS
*/
public String getUvus(){
return uvus;
}
/**
* Función que devuelve el fichero del alumno.
*
* @return Fichero
* @throws InterruptedException
* @throws IOException
*/
public Fichero getFichero() throws IOException, InterruptedException{
fichero = new Fichero("./Examen");
return fichero;
}
}
113 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Ventana.java /**
* Trabajo final de grado
* Clase ventana. Interfaz gráfica del programa utilizando la biblioteca
Swing.
* En esta interfaz se muestra una etiqueta que nos informa del último paso
realizado y
* un texto que nos informa sobre el resultado obtenido. Además se muestran
diferentes
* botones para la realización de las distintas funciones y una animación de
buffering
* mientras el sistema realiza las distintas funciones.
*
* @author Andrés Martínez Gotor
*/
package alumnoExamen;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Ventana extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel vtexto1;
private JTextArea vtexto2;
private JPanel panel;
private JButton reenviarButton;
private JButton apartado0;
private JButton apartado1;
private JButton apartado2;
private JButton apartado3;
private JButton quitButton;
private ImageIcon img;
private JLabel imagen0;
private JLabel imagen1;
private JLabel imagen2;
private JLabel imagen3;
private JLabel buff;
Ventana ventana = this;
// Alumno utilizado
private Alumno alumno;
// Conexion utilizada
private Comunicacion conexion;
/**
* Contructor de la clase. Se crea un nuevo panel y se establece el título y
* las dimensiones utilizadas, así como el resto de características básicas.
*
* @param alumnoRec
* Alumno que ejecuta la interfaz gráfica
114 – BLOQUE 6. Anexos – Anexo 2. Código fuente
* @param conexionRec
* Conexión extablecida con el servidor
* @throws IOException
*/
public Ventana(Alumno alumnoRec, Comunicacion conexionRec)
throws IOException {
// Guardamos referencia a alumno
alumno = alumnoRec;
// Guardamos referncia a la conexion
conexion = conexionRec;
// Creamos el panel
panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(null);
// Introducimos el título
setTitle("Examen FP2");
// Establecemos las dimensiones del panel.
setSize(500, 500);
// Inicializamos las imágenes y el texto.
img = new ImageIcon("system/images/tick.png");
imagen0 = new JLabel(img);
imagen1 = new JLabel(img);
imagen2 = new JLabel(img);
imagen3 = new JLabel(img);
vtexto1 = new JLabel("");
vtexto2 = new JTextArea("");
// Buffering
buff = new JLabel();
ImageIcon imageIcon = new ImageIcon("system/images/buff.gif");
buff.setIcon(imageIcon);
imageIcon.setImageObserver(buff);
buff.setBounds(170, 100, 200, 100);
panel.add(buff);
buff.setVisible(false);
// Establecemos la posición de la ventana y la función asociada a
// cerrarla.
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
/**
* Función que establece el texto de la etiqueta utilizada. Borra el texto
* que estuviese escrito anteriormente y lo sustituyo por el nuevo.
*
* @param texto
* texto a introducir
*/
public void setTexto1(String texto) {
panel.remove(vtexto1);
vtexto1 = new JLabel(texto);
vtexto1.setBounds(10, 10, 200, 40);
vtexto1.setSize(500, 100);
panel.add(vtexto1);
panel.revalidate();
panel.repaint();
}
/**
* Función que establece el texto del campo de texto. Borra el texto que
* estuviese escrito anteriormente y lo sustituyo por el nuevo.
*
* @param texto
* texto a introducir
*/
public void setTexto2(String texto) {
115 – BLOQUE 6. Anexos – Anexo 2. Código fuente
panel.remove(vtexto2);
vtexto2 = new JTextArea(texto);
vtexto2.setBounds(10, 100, 200, 40);
vtexto2.setSize(480, 100);
vtexto2.setLineWrap(true);
vtexto2.setWrapStyleWord(true);
vtexto2.setBorder(BorderFactory.createEmptyBorder(10, 10, 15, 10));
vtexto2.setVisible(true);
panel.add(vtexto2);
panel.revalidate();
panel.repaint();
}
/**
* Función que añade los botones y les asocia las distintas funciones del
* programa.
*
* @throws InterruptedException
* @throws IOException
*/
public void addButtons() throws IOException, InterruptedException {
// Botón para reenviar el código
reenviarButton = new JButton("Reenviar código");
reenviarButton.setBounds(20, 250, 200, 40);
// Botón para realizar el Apartado0
apartado0 = new JButton("Apartado0");
apartado0.setBounds(260, 250, 200, 40);
// Botón para realizar el Apartado1
apartado1 = new JButton("Apartado1");
apartado1.setBounds(20, 320, 200, 40);
// Botón para realizar el Apartado2
apartado2 = new JButton("Apartado2");
apartado2.setBounds(260, 320, 200, 40);
// Botón para realizar el Apartado3
apartado3 = new JButton("Apartado3");
apartado3.setBounds(20, 390, 200, 40);
// Botón para cerrar el programa
quitButton = new JButton("Salir");
quitButton.setBounds(260, 390, 200, 40);
// Función para el boton de cerrar
quitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
// Función para el boton de reenviar
reenviarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Reenviando código:");
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 10);
}
});
// Función para el boton de apartado0
apartado0.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Ejecutando Apartado0:");
ventana.setTexto2("");
116 – BLOQUE 6. Anexos – Anexo 2. Código fuente
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 0);
}
});
// Función para el boton de apartado1
apartado1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Ejecutando Apartado1:");
ventana.setTexto2("");
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 1);
}
});
// Función para el boton de apartado2
apartado2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Ejecutando Apartado2:");
ventana.setTexto2("");
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 2);
}
});
// Función para el boton de apartado3
apartado3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
ventana.setTexto1("Ejecutando Apartado3:");
ventana.setTexto2("");
// Creamos animacion buffering
setBuff();
new Hilo(ventana, 3);
}
});
panel.add(quitButton);
panel.add(reenviarButton);
panel.add(apartado0);
panel.add(apartado1);
panel.add(apartado2);
panel.add(apartado3);
panel.revalidate();
panel.repaint();
}
/**
* Función que elimina los botones para realizar los distintos apartados.
*
* @param ventana
* Ventana de la que se eliminan los botones
*/
public void delButtons(Ventana ventana) {
if (ventana.apartado0 != null) {
panel.remove(ventana.reenviarButton);
panel.remove(ventana.apartado0);
panel.remove(ventana.apartado1);
117 – BLOQUE 6. Anexos – Anexo 2. Código fuente
panel.remove(ventana.apartado2);
panel.remove(ventana.apartado3);
}
panel.revalidate();
panel.repaint();
}
/**
* Función que muestra una imagen de confirmación en un determinado
* apartado.
*
* @param apartado
* apartado para el que se debe mostrar el tick
*/
public void tick(int apartado) {
switch (apartado) {
case 0:
imagen0.setBounds(380, 250, 200, 40);
panel.add(imagen0);
break;
case 1:
imagen1.setBounds(140, 320, 200, 40);
panel.add(imagen1);
break;
case 2:
imagen2.setBounds(380, 320, 200, 40);
panel.add(imagen2);
break;
case 3:
imagen3.setBounds(140, 390, 200, 40);
panel.add(imagen3);
break;
}
panel.revalidate();
panel.repaint();
}
/**
* Función que elimina las imágenes de confirmación.
*/
public void delTick() {
panel.remove(imagen0);
panel.remove(imagen1);
panel.remove(imagen2);
panel.remove(imagen3);
panel.revalidate();
panel.repaint();
}
/**
* Función que muestra la animación de buffering.
*
* @throws InterruptedException
*/
public void setBuff() {
ventana.setTexto2("");
buff.setVisible(true);
}
/**
* Función que elimina la animación de buffering.
*/
public void delBuff() {
buff.setVisible(false);
}
118 – BLOQUE 6. Anexos – Anexo 2. Código fuente
/* A partir de ahora se definen las funciones asociadas a los distintos
botones */
/**
* Función que gestiona el registro de un usuario en el sistema. Realiza las
* siguientes funciones:
* - Envía el UVUS del alumno.
* - Envía el fichero del alumno.
* - Recibe la confirmación del servidor y muestra en una ventana el
* resultado del proceso.
*
* @throws UnknownHostException
* @throws IOException
* @throws InterruptedException
*/
public int registraAlumno() throws IOException, ClassNotFoundException,
InterruptedException {
int res = 0;
try {
// Establecemos conexion con el servidor
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("registra2");
// Enviamos el nombre del alumno
conexion.enviaMensaje(alumno.getUvus());
// Recibimos confirmación del servidor
int resultado = conexion.recibeInt();
if (resultado == 1) {
ventana.setTexto2("Nombre de usuario no valido. Por favor, compruebe
que ha introducido "
+ "un nombre de usuario válido y vuelva a intentarlo.");
} else if (resultado == 2) {
// Iniciamos la transferencia
try {
// Enviamos el fichero
ventana.setTexto2("Enviando su fichero...");
conexion.enviaFichero(alumno.getFichero());
// Recibimos confirmación del servidor
int conf = conexion.recibeInt();
if (conf == 1) {
ventana.setTexto2("Su fichero se ha enviado correctamente.");
conexion.cierraConex();
// Si los ficheros makefile no han sido modificados,
// procedemos a la ejecución
if (compruebaMake()) {
// Continuamos la ejecución
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("rm ./Examen.zip ");
p.waitFor();
// Continuamos la ejecución
ventana.delTick();
res = 1;
} else {
ventana.delButtons(ventana);
}
} else {
conexion.cierraConex();
ventana.setTexto2("Se ha producido un error enviando el
fichero. Por favor, vuelva a intentarlo.");
}
119 – BLOQUE 6. Anexos – Anexo 2. Código fuente
} catch (FileNotFoundException e) {
conexion.cierraConex();
ventana.setTexto2("Fichero no encontrado. Asegúrese de que
dispone de la carpeta Examen en el directorio de ejecución y vuelva a
intentarlo.");
}
} else {
conexion.cierraConex();
ventana.setTexto2("Error al conectar con la base de datos del
servidor.");
}
} catch (ConnectException e) {
ventana.setTexto2("Error al conectar con el servidor. Por favor,
cierre el programa y vuelva a intentarlo"
+ ", si el problema persiste pónganse en contacto con el
profesor.");
}
return res;
}
/**
* Función que gestiona la petición de realizacion de la prueba
* correspondiente a un apartado.
*
* @param apartado
* número de apartado a gestionar
* @throws UnknownHostException
* @throws IOException
* @throws InterruptedException
*/
public void peticionApartado(int apartado) throws UnknownHostException,
IOException, InterruptedException {
// Realizamos la conexión
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("apartado" + apartado);
// Iniciamos temporizador
Temporizador temp = new Temporizador(conexion, ventana, 20);
// Enviamos el nombre del alumno
conexion.enviaMensaje(alumno.getUvus());
// Recibimos confirmación del servidor
try {
int resultado = conexion.recibeInt();
if (resultado == 4) {
ventana.setTexto2("Error al ejecutar el Apartado"
+ apartado
+ ". Por favor, asegurese de que está incluido el fichero
\"a.out\" en su fichero comprimido.");
} else if (resultado == 1) {
conexion.recibeFichero("./errorApartado" + apartado);
ventana.setTexto2("Error al ejecutar el Apartado"
+ apartado
+ ". Por favor, asegurese de que pasa las pruebas de manera
local y vuelva a intentarlo.\n"
+ "Se ha generado el fichero errorApartado" + apartado
+ " con la salida obtenida.");
} else if (resultado == 2) {
ventana.setTexto2("Error en la gestión de memoria. Para más
información ejecute la herramienta de manera local y observe los ficheros" +
120 – BLOQUE 6. Anexos – Anexo 2. Código fuente
"del directorio herramienta/pruebas/MemoryRep");
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("rm errorApartado"+ apartado);
p.waitFor();
} else if (resultado== 3) {
ventana.setTexto2("Ejecución del Apartado"+apartado+" completado
satisfactoriamente");
ventana.tick(apartado);
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("rm errorApartado"+ apartado);
p.waitFor();
} else if (resultado==10){
ventana.setTexto2("Error de compilación. Asegúrese de pasar las
pruebas de manera local y vuelva a intentarlo.");
}else {
ventana.setTexto2("Error al conectar con el servidor. Vuelva a
intentarlo");
}
} catch (SocketException e) {
}
// Cancelamos temporizador
temp.cancelar();
}
/**
* Función que comprueba que los ficheros makefile de los distintos
* apartados no han sido modificados. En caso de haberse producido algún
* cambio puede desembocar en un falso positivo o negativo
*
* @return
* @throws IOException
* @throws InterruptedException
*/
public Boolean compruebaMake() throws IOException, InterruptedException {
Boolean ret = true;
// Realizamos la conexión
conexion.estableceConex();
// Enviamos la opción a realizar
conexion.enviaMensaje("compruebaMake");
// Enviamos el nombre del alumno
conexion.enviaMensaje(alumno.getUvus());
// Recibimos confirmación del servidor
int res = conexion.recibeInt();
if (res > 0) {
ventana.setTexto2("El fichero examenPFEDAptdo"
+ res
+ " ha sido modificado, compruebe que el contenido es EXACTAMENTE
el mismo que el original y vuelva a intentarlo.");
ret = false;
}
return ret;
}
}
121 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Hilo.java /**
* Trabajo final de grado
* Clase Hilo. Genera un nuevo hilo que realiza una función básica del
sistema.
*
* @author Andrés Martínez Gotor
*/
package alumnoExamen;
import java.io.IOException;
public class Hilo implements Runnable {
private Thread t;
private int opcion;
private Ventana ventana;
/**
* Constructor de la clase. Recibe como parámetros los elementos necesarios
* para la gestión de las peticiones.
*
* @param ventanaRec
* interfaz gráfica utilizada
* @param opcionRec
* opción elegida por el alumno (registo o ejecución de un
* apartado)
*/
Hilo(Ventana ventanaRec, int opcionRec) {
t = new Thread(this);
opcion = opcionRec;
ventana= ventanaRec;
t.start();
}
/**
* Función que realiza cada uno de los hilos creados. Obtiene la opción a
* realizar y llama a la función correspondiente.
*/
public void run() {
try {
switch (opcion) {
case 10:
ventana.registraAlumno();
break;
default:
ventana.peticionApartado(opcion);
break;
}
ventana.delBuff();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
122 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Fichero.java /**
* Trabajo final de grado
* Clase fichero. Contiene los atributos y los métodos necesarios para la
transferencia de un fichero.
*
* @author Andrés Martínez Gotor
*/
package alumnoExamen;
import java.io.File;
import java.io.IOException;
public class Fichero {
private File fichero;
private byte[] bytearray;
int size;
/**
* Contructor de la clase. Almacena el fichero, su tamaño y la secuencia de
* bytes que lo componen.
*
* @param rutaFichero
* ruta del fichero a utilizar
* @throws IOException
* @throws InterruptedException
*/
public Fichero(String rutaFichero) throws IOException, InterruptedException
{
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("zip -r Examen.zip "+rutaFichero);
p.waitFor();
fichero = new File("./Examen.zip");
size = (int) fichero.length();
bytearray = new byte[size];
}
/**
* Constructor por defecto
*/
public Fichero() {
}
/**
* Función que devuelve el fichero utilizado.
*
* @return fichero utilizado
*/
public File getFichero() {
return this.fichero;
}
/**
* Función que devuelve la secuencia de bytes del fichero.
*
* @return cadena de bytes del fichero
*/
public byte[] getByteArray() {
return this.bytearray;
}
/**
* Función que devuelve el tamaño del fichero.
*
* @return tamaño del fichero
*/
123 – BLOQUE 6. Anexos – Anexo 2. Código fuente
public int getTam() {
return this.size;
}
}
124 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Temporizador.java /**
* Trabajo final de grado
* Clase Temporizador. Asegura que el sistema no se quede bloqueado
* en caso de producirse un bucle en la gestión del código del alumno.
*
* @author Andrés Martínez Gotor
*/
package alumnoExamen;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import alumnoExamen.Ventana;
public class Temporizador {
private Timer temp;
private Ventana ventana;
private Comunicacion conexion;
private TimerTask venceTemp = new TimerTask() {
@Override
public void run() {
ventana.setTexto2("Ha vencido el temporizador. Posible bucle infinito
o sobrecarga del servidor. "
+ "Asegurese del correcto funcionamiento de su programa y vuelva
a intentarlo");
ventana.delBuff();
try {
conexion.cierraConex();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
/**
* Constructor del temporizador. Programa el evento de vencimiento del
* temporizador. Este evento cierra la conexión establecida y muestra un
* mensaje de error.
*
* @param conexionRec
* conexión establecida cliente-servidor
* @param ventanaRec
* interfaz gráfica utilizada
* @param segundos
* segundos hasta vencer el temporizador
*/
public Temporizador(Comunicacion conexionRec, Ventana ventanaRec,
int segundos) {
ventana = ventanaRec;
conexion = conexionRec;
temp = new Timer();
temp.schedule(venceTemp, segundos * 1000);
}
/**
* Función que cancela el temporizador.
*/
public void cancelar() {
temp.cancel();
}
}
125 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Servidor Principal.java /**
* Trabajo final de grado
* Programa principal para el equipo servidor
*
* @author Andrés Martínez Gotor
*/
package servidor;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Scanner;
public class Principal {
/**
* Método main. Se crea un servidor con un socket a la espera de nuevas
* peticiones. Se conecta a la base de datos y se administran las
* peticiones.
* <p>
* Para cada petición se crea un nuevo hilo que la gestiona.
*
* @param args
* @throws ClassNotFoundException
* @throws InterruptedException
* @throws MongoException
* @see Alumno
*/
public static void main(String[] args) throws IOException,
ClassNotFoundException, InterruptedException {
System.out.println("Ejecutando servidor:");
ServerSocket serverSocket = new ServerSocket(8888);
String opcion;
// Conectamos con la base de datos
DataBase mongo= new DataBase("localhost");
//Preguntamos si queremos crear una base de datos nueva
System.out.println("¿Quiere crear una base de datos nueva? [S/n]");
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
char c = sc.next(".").charAt(0);
if(c=='S'){
System.out.println("¿Está seguro? Se borrarán los datos almacenados
anteriormente en la base de datos. [S/n]");
c = sc.next(".").charAt(0);
if(c=='S'){
mongo.borraDatos();
System.out.println("Creada nueva base de datos.");
}
} else {
if(c!='n'){
System.out.println("Caracter no reconocido. Comportamiento por
defecto.");
}
System.out.println("Utilizando datos almacenados.");
}
//sc.close();
// Introducimos la lista de alumnos en la base de datos
126 – BLOQUE 6. Anexos – Anexo 2. Código fuente
mongo.creaLista("listafp2.txt");
// Preparamos impresión de fichero
new Hilo("imprime",mongo);
//Ejecutamos procedimiento principal.
while (true) {
try{
// Comprobamos que tenemos conexión con la base de datos
mongo.compruebaConex();
// Nueva conexión
Comunicacion conexion=new Comunicacion(serverSocket);
// Recibimos función a realizar
opcion = conexion.recibeString();
//Creamos un hilo para la petición del alumno
new Hilo(opcion,conexion, mongo);
} catch (com.mongodb.MongoException e) {
System.out.println("No se pudo conectar con la base de datos");
serverSocket.close();
} catch (Exception e){}
}
}
}
127 – BLOQUE 6. Anexos – Anexo 2. Código fuente
DataBase.java /**
* Trabajo final de grado
* Clase DataBase. Contiene los atributos y los métodos necesarios para la
gestión
* de la base de datos de notas de los alumnos.
*
* @author Andrés Martínez Gotor
*/
package servidor;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.util.Scanner;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
public class DataBase {
private BasicDBObject doc;
private DBCollection coll;
private DB db;
/**
* Constructor de la clase. Realiza la conexión con la base de datos.
*
* @param IP
* IP donde se encuentra la base de datos
* @throws UnknownHostException
*/
public DataBase(String IP) throws UnknownHostException {
MongoClient mongoClient = new MongoClient(IP);
// Conecta con la base de datos
db = mongoClient.getDB("fp2");
// Obtiene la colección
coll = db.getCollection("clasefp2");
}
/**
* Función que imprime el fichero de notas y finaliza el programa. Queda a
* la espera de confirmación por parte del usuario para finalizar el
* programa y imprimir el fichero de notas. Las notas se obtienen de la base
* de datos como documentos JSON, estos se guardan en una variable
* javascript para representar el resultado. Alternativamente se imprimen
las
* notas en un fichero txt para su representación en una hoja de cálculo.
*
* @throws FileNotFoundException
* @throws UnsupportedEncodingException
*/
public void imprimeNotas() throws FileNotFoundException,
UnsupportedEncodingException {
System.out
.println("Presione intro cuando quiera imprimir el fichero de notas
y cerrar el programa.");
Scanner sc = new Scanner(System.in);
128 – BLOQUE 6. Anexos – Anexo 2. Código fuente
sc.nextLine();
sc.close();
DBCursor cursor = coll.find();
// Fichero javascript
PrintWriter writer = new PrintWriter("./notas/fp2.js", "UTF-8");
// Fichero txt
PrintWriter writer2 = new PrintWriter("./notas/notas.txt", "UTF-8");
writer2.println("UVUS\tNombre\tApellidos\tTrabajo\tApartado0\tApartado1\tApa
rtado2\tApartado3");
writer.println("var mydata = [");
try {
while (cursor.hasNext()) {
// Obtenemos los datos del alumno
DBObject alumno = cursor.next();
// Imprimimos el objeto JSON tal cual para el fichero js
writer.println(alumno + ",");
// Extraemos los campos necesarios para el fichero txt
String notas = new
String(alumno.get("_id")+"\t"+alumno.get("Nombre")+"\t"+alumno.get("Apellidos"
)+"\t"+alumno.get("PFED")
+"\t"+alumno.get("apartado0")+"\t"+alumno.get("apartado1")+"\t"+alumno.get("
apartado2")+"\t"+alumno.get("apartado3"));
writer2.println(notas.replaceAll("null", " "));
}
} finally {
cursor.close();
}
writer.println("]");
writer.close();
writer2.close();
System.out
.println("Fichero de notas impreso. Abra los ficheros
/notas/notas.html para ver el resultado.");
System.exit(0);
}
/**
* Función que publica una nota en la base de datos.
*
* @param uvus
* identificador de Usuario Virtual de la Universidad de Sevilla
* @param apartado
* apartado en el que se publicará la nota
* @param nota
* nota a publicar
*/
public void publicaNota(String uvus, String apartado, int nota) {
BasicDBObject alumnoDB = new BasicDBObject();
alumnoDB.append("$set", new BasicDBObject().append(apartado, 10));
BasicDBObject searchQuery = new BasicDBObject().append("_id", uvus);
coll.update(searchQuery, alumnoDB);
}
/**
* IMPORTANTE! El formato de la lista debe ser una línea por alumno y seguir
* el formato: "APELLIDOS, NOMBRE uvus" manteniendo mayúsculas y minúsculas.
*
* Función que crea la lista de alumnos a partir de un fichero de datos.
*
* @param licheroLista
129 – BLOQUE 6. Anexos – Anexo 2. Código fuente
* Ruta del fichero con la lista de alumno a utilizar
*/
public void creaLista(String ficheroLista) {
Scanner sc2 = null;
boolean control = true;
try {
sc2 = new Scanner(new File(ficheroLista));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Leemos todas las lineas del fichero.
while (sc2.hasNextLine()) {
String apellido = "";
String nombre = "";
String uvus = "";
Scanner s2 = new Scanner(sc2.nextLine());
// Obtenemos los apellidos. Que se caracterizan por acabar con una
// coma
while (control && s2.hasNext()) {
String s = s2.next();
apellido = apellido + s + " ";
if ((s.charAt(s.length() - 1)) == ',') {
control = false;
apellido = apellido.replaceAll(", ", "");
}
}
control = true;
// Leemos el nombre y el uvus (el uvus se caracteriza por utilizar
// letras minúsculas)
while (control && s2.hasNext()) {
String s = s2.next();
if (((s.charAt(s.length() - 1)) >= 'A' && (s
.charAt(s.length() - 1)) <= 'Z')
|| (s.charAt(s.length() - 1) == 'ª')
|| (s.charAt(s.length() - 1) == '.')) {
nombre = nombre + s + " ";
} else {
// Eliminamos el último espacio guardado del nombre
nombre = nombre.substring(0, nombre.length() - 1);
// Guardamos el UVUS
uvus = s;
control = false;
}
}
control = true;
// Leemos hasta el final de la linea
while (s2.hasNext()) {
s2.next();
}
s2.close();
// Guardamos los datos en la base de datos
doc = new BasicDBObject("_id", uvus);
doc.append("Nombre", nombre);
doc.append("Apellidos", apellido);
// Comprobamos que el usuario no se encuentre ya en
// la base de datos
try {
coll.insert(this.doc);
} catch (MongoException e) {
}
}
130 – BLOQUE 6. Anexos – Anexo 2. Código fuente
}
/**
* Función que comprueba que la base de datos se encuentra disponible
* obteniendo la primera entrada.
*/
public void compruebaConex() {
coll.findOne();
}
/**
* Función que elimina los datos de la base de datos.
*/
public void borraDatos() {
DBCursor cursor = coll.find();
try {
while (cursor.hasNext()) {
coll.remove(cursor.next());
}
} finally {
cursor.close();
}
}
/**
* Funcion que devuelve 2 si un alumno si se encuentra en la base de
* datos o 1 en caso contrario.
*
* @param uvus
* UVUS del alumno
*/
public int compruebaAlumno(String uvus) {
doc = new BasicDBObject("_id", uvus);
int res =1;
// Comprobamos que el usuario no se encuentre ya en
// la base de datos
try {
coll.find(this.doc).next();
res=2;
// Si no existe producirá una excepción
} catch (Exception e) {
res=1;
}
return res;
}
}
131 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Comunicacion.java /**
* Trabajo final de grado
* Clase Comunicación. Contiene los atributos y los métodos necesarios para la
gestión de la comunicación cliente-servidor.
*
* @author Andrés Martínez Gotor
*/
package servidor;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Comunicacion {
private Socket socket;
/**
* Constructor de la clase. Recibe como parámetro el socket de servidor y
* queda a la espera de nuevas conexiones. Cuando se produce una conexión
* guarda el socket correspondiente.
*
* @param serverSocket
* socket servidor
* @throws IOException
*/
public Comunicacion(ServerSocket serverSocket) throws IOException {
socket = serverSocket.accept();
System.out.println("Accepted connection : " + socket);
}
/**
* Función que cierra la conexión.
*
* @throws IOException
*/
public void cierraConex() throws IOException {
socket.close();
}
/**
* Función que recibe un objeto tipo String.
*
* @return devuelve el objeto String recibido
* @throws IOException
* @throws ClassNotFoundException
*/
public String recibeString() throws IOException, ClassNotFoundException {
InputStream istream = socket.getInputStream();
132 – BLOQUE 6. Anexos – Anexo 2. Código fuente
ObjectInput in = new ObjectInputStream(istream);
return (String) in.readObject();
}
/**
* Función que recibe un objeto tipo entero.
*
* @return devuelve el objeto entero recibido
* @throws IOException
*/
public int recibeInt() throws IOException {
DataInputStream istream = new DataInputStream(socket.getInputStream());
return istream.readInt();
}
/**
* Función que envía un objeto de tipo entero.
*
* @param mensaje
* entero a enviar
* @throws IOException
*/
public void enviaMensaje(int mensaje) throws IOException {
DataOutputStream ostream = new DataOutputStream(
socket.getOutputStream());
ostream.writeInt(mensaje);
ostream.flush();
}
/**
* Función que envía un objeto de tipo String.
*
* @param mensaje
* String a enviar
* @throws IOException
*/
public void enviaMensaje(String mensaje) throws IOException {
OutputStream ostream = socket.getOutputStream();
ObjectOutput s = new ObjectOutputStream(ostream);
s.writeObject(mensaje);
s.flush();
}
/**
* Función que recibe un fichero comprimido. Primero se recibe el tamaño del
* fichero y luego se recibe el fichero en sí. Este fichero se almacena en
* la carpeta del usuario que lo ha enviado y se descomprime.
*
* @param uvus
* identificador de Usuario Virtual de la Universidad de Sevilla
*
* @return 1 si la transferencia se ha realizado correctamente 0 en caso
* contrario
* @throws IOException
* @throws ClassNotFoundException
* @throws InterruptedException
*/
public int recibeFichero(Alumno alumno) throws IOException,
ClassNotFoundException, InterruptedException {
// Recibimos el tamaño del fichero
InputStream istream = socket.getInputStream();
ObjectInput in = new ObjectInputStream(istream);
int filesize = (int) in.readObject();
int resultado = 0;
Runtime runtime;
Process p;
133 – BLOQUE 6. Anexos – Anexo 2. Código fuente
// Recibimos el fichero
int bytesRead = 0; // Bytes leidos en una iteración del bucle
int currentTot = 0; // Bytes leidos hasta el momento
byte[] bytearray = new byte[filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("./" + alumno.getUvus()
+ "/fichero.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray, 0, bytearray.length);
currentTot = bytesRead;
while (bytesRead > -1 && currentTot < filesize) {
bytesRead = is.read(bytearray, currentTot,
(bytearray.length - currentTot));
if (bytesRead >= 0)
currentTot += bytesRead;
}
bos.write(bytearray, 0, currentTot);
bos.flush();
// Descomprimimos y comprobamos que están todos los ficheros
// necesarios
runtime = Runtime.getRuntime();
p = runtime.exec("unzip ./" + alumno.getUvus() + "/fichero.zip -d ./"
+ alumno.getUvus());
p.waitFor();
bos.close();
// Comprobamos que realmente existen ficheros en la carpeta del alumno
runtime = Runtime.getRuntime();
p = runtime.exec("ls ./" + alumno.getUvus());
p.waitFor();
is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
// Leemos la salida del comando "ls", si existe alguna línea es que
// se han transferido los ficheros
if (br.readLine() != null) {
resultado = 1;
}
return resultado;
}
/**
* Función que envía un fichero. Primero se manda el tamaño del fichero y
* luego el fichero en si.
*
* @param socket
* socket de la conexión
*
* @see Fichero
* @throws IOException
*/
public void enviaFichero(Fichero fichero) throws IOException {
// Enviamos el tamaño del fichero
enviaMensaje(fichero.getTam());
// Enviamos el fichero
byte[] bytearray = fichero.getByteArray();
FileInputStream fin = new FileInputStream(fichero.getFichero());
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray, 0, bytearray.length);
OutputStream os = socket.getOutputStream();
os.write(bytearray, 0, bytearray.length);
os.flush();
bin.close();
}
}
134 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Alumno.java /**
* Trabajo final de grado
* Clase Alumno-Servidor. Contiene los atributos y métodos necesarios para la
gestión
* del trabajo del alumno, tanto la realización de la PFED como el examen
posterior.
*
* @author Andrés Martínez Gotor
*/
package servidor;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.SocketException;
public class Alumno {
private String uvus;
private int res;
private Comunicacion conexion;
private DataBase baseDeDatos;
/**
* Constructor principal. Recibe como parámetros la conexión con el cliente
* y la base de datos en la que debe introducirse.
*
* @param socket
* socket de conexión con el cliente.
* @param coll
* colección utilizada en la base de datos para incluir a los
* alumnos.
* @throws IOException
* @throws ClassNotFoundException
* @throws InterruptedException
*/
public Alumno(Comunicacion conexionRec, DataBase baseDeDatosRec) {
// Guardamos los parámetros de conexion y la base de datos
conexion = conexionRec;
baseDeDatos = baseDeDatosRec;
}
/**
* Función que realiza el registro de un alumno en el sistema. Se comprueba
* que está en la lista y si no ha sido introducido anteriormente, se
* registra en la base de datos.
* <p>
* En el caso de que los anteriores pasos hayan finalizado de manera
* satisfactoria se inicia la transferencia del fichero con el trabajo
* comprimido del alumno. Una vez se ha finalizado la transferencia, se
* descomprime el fichero y se comprueba que todo ha finalizado
* correctamente.
*
* @param opcion
* 1 si se trata de la corrección de la PFED y 2 en caso del
* examen.
* @throws ClassNotFoundException
* @throws IOException
* @throws InterruptedException
*/
public void registra(int opcion) throws ClassNotFoundException,
135 – BLOQUE 6. Anexos – Anexo 2. Código fuente
IOException, InterruptedException {
try {
// Recibimos el nombre del alumno
uvus = conexion.recibeString();
// Comprobamos nombre del alumno en BBDD
res = 0;
// Comprobamos conectividad con la base de datos
try {
baseDeDatos.compruebaConex();
res = 1;
// Comprobamos que el alumno está en la lista
res = baseDeDatos.compruebaAlumno(uvus);
} catch (com.mongodb.MongoException e) {
res = 0;
System.out.println("No se pudo conectar con la base de datos");
}
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
// Si todo ha ido bien
if (res == 2) {
// Creación de la carpeta del alumno
creaCarpeta(opcion);
// TRANSFERENCIA DE FICHEROS
res = conexion.recibeFichero(this);
// Todo ha ido bien. Informamos al alumno.
conexion.enviaMensaje(res);
}
} catch (SocketException | ArrayIndexOutOfBoundsException e) {
System.out
.println("Ha habido algún error en la transferencia de los
ficheros");
}
}
/**
* Función que borra el contenido de la carpeta de un alumno (si existe) o
* la crea en caso contrario.
*
* @param opcion
* 1 si debe crear la carpeta para la PFED o 2 para el examen
* @throws IOException
* @throws InterruptedException
*/
private void creaCarpeta(int opcion) throws IOException,
InterruptedException {
Runtime runtime;
Process p;
if (opcion == 1) {
runtime = Runtime.getRuntime();
p = runtime.exec("rm -r ./" + uvus + "/PFED/");
p.waitFor();
p = runtime.exec("mkdir " + uvus);
p.waitFor();
} else {
runtime = Runtime.getRuntime();
p = runtime.exec("rm -r ./" + uvus + "/Examen/");
p.waitFor();
p = runtime.exec("mkdir " + uvus);
136 – BLOQUE 6. Anexos – Anexo 2. Código fuente
p.waitFor();
}
}
/**
* Función que corrige la ejecución de un determinado apartado.
*
* @param apartado
* apartado a corregir
* @throws ClassNotFoundException
* @throws IOException
* @throws InterruptedException
*/
public void corrigeApartado(int apartado) throws ClassNotFoundException,
IOException, InterruptedException {
Runtime runtime;
Process p;
PrintWriter writer;
// Recibimos el nombre del alumno
uvus = conexion.recibeString();
// Introducimos y comprobamos nombre del alumno en BBDD
res = 0;
// Comprobamos conectividad con la base de datos
try {
baseDeDatos.compruebaConex();
res = 1;
} catch (com.mongodb.MongoException e) {
res = 0;
System.out.println("No se pudo conectar con la base de datos");
}
if (res == 1) {
// Si es el Apartado0 tiene un tratamiento especial
if (apartado == 0) {
runtime = Runtime.getRuntime();
// Eliminamos si existe el resumen del informe de la gestión de
// memoria dinámica
p = runtime.exec("rm ./" + uvus
+ "/Examen/Apartado0/herramienta/ResumenMemoryReport");
p.waitFor();
runtime = Runtime.getRuntime();
// Ejecutamos la herramienta
p = runtime.exec("make -s -C ./" + uvus
+ "/Examen/Apartado0/herramienta/ -f Herramienta");
p.waitFor();
// Comprobamos que no hay errores de compilación
InputStream e = p.getErrorStream();
InputStreamReader isr = new InputStreamReader(e);
BufferedReader br = new BufferedReader(isr);
br.readLine();
if ((br.readLine()) == null) {
// Guardamos la salida del comando del makefile
InputStream is = p.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
writer = new PrintWriter("./" + uvus + "/salidaMake",
"UTF-8");
String line;
while ((line = br.readLine()) != null) {
if (!line.contains("make:"))
writer.println(line);
137 – BLOQUE 6. Anexos – Anexo 2. Código fuente
}
writer.close();
// Comprobamos que la salida producida es correcta
runtime = Runtime.getRuntime();
p = runtime.exec("cat ./" + uvus + "/salidaMake");
p.waitFor();
is = p.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
// Si se imprime algo no esperado es que la salida no es
// correcta
boolean control = true;
while ((line = br.readLine()) != null && control) {
if (!line.contains("__")) {
control = false;
}
}
if (control) {
res = 2;
// Comprobamos la gestión de memoria
File fichero = new File(
"./"
+ uvus
+
"/Examen/Apartado0/herramienta/ResumenMemoryReport");
// Si el fichero está vacío no hay errores de memoria.
if (fichero.length() == 0) {
res = 3;
}
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
baseDeDatos.publicaNota(uvus, "apartado0", 10);
} else {
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
// La salida no es correcta. Enviamos informe al alumno
conexion.enviaFichero(new Fichero("./" + uvus
+ "/salidaMake"));
}
} else {
// Caso de no compilar
conexion.enviaMensaje(10);
}
} else {
// Si no es el apartado0
// Renombramos el fichero a.out del alumno para conservarlo
runtime = Runtime.getRuntime();
p = runtime.exec("mv ./" + uvus + "/Examen/Apartado"
+ apartado + "/a.out ./" + uvus + "/Examen/Apartado"
+ apartado + "/a2.out");
p.waitFor();
// Ejecutamos la herramienta
runtime = Runtime.getRuntime();
p = runtime.exec("make -C ./" + uvus + "/Examen/Apartado"
+ apartado + "/ -s -B -f examenPFEDAptdo" + apartado);
p.waitFor();
// Comprobamos que no hay errores de compilación
InputStream e = p.getErrorStream();
InputStreamReader isr = new InputStreamReader(e);
BufferedReader br = new BufferedReader(isr);
138 – BLOQUE 6. Anexos – Anexo 2. Código fuente
br.readLine();
if ((br.readLine()) == null) {
// Guardamos la salida del comando del makefile
InputStream is = p.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
writer = new PrintWriter("./" + uvus + "/salidaApartado"
+ apartado, "UTF-8");
String line;
// Si la salida contiene alguna línea inesperada la
// imprimimos
while ((line = br.readLine()) != null) {
if (!line
.contains("Si el comando diff no muestra nada el
resultado es correcto")) {
if (!line.contains("make:"))
writer.println(line);
}
}
writer.close();
// Comprobamos que la salida producida es correcta
File fichero = new File("./" + uvus + "salidaApartado"
+ apartado);
// Si el fichero está vacío es que todo ha ido bien.
if (fichero.length() == 0) {
res = 3;
baseDeDatos
.publicaNota(uvus, "apartado" + apartado, 10);
conexion.enviaMensaje(res);
} else {
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
conexion.enviaFichero(new Fichero("./" + uvus
+ "/salidaApartado" + apartado));
}
} else {
// Caso de no compilar
conexion.enviaMensaje(10);
}
}
}
}
/**
* Función que comprueba que los ficheros makefile de los distintos
* apartados no han sido modificados. En caso de haberse producido algún
* cambio puede desembocar en un falso positivo o negativo
*
* @return
* @throws IOException
* @throws InterruptedException
* @throws ClassNotFoundException
*/
public void compruebaMake() throws ClassNotFoundException, IOException,
InterruptedException {
Runtime runtime;
Process p;
InputStream is;
InputStreamReader isr;
BufferedReader br;
int res = 0;
// Recibimos el nombre del alumno
uvus = conexion.recibeString();
139 – BLOQUE 6. Anexos – Anexo 2. Código fuente
for (int i = 1; (i <= 3) && res == 0; i++) {
// Comprobamos que los ficheros no han sido modificados
runtime = Runtime.getRuntime();
p = runtime.exec("diff ./" + uvus + "/Examen/Apartado" + i
+ "/examenPFEDAptdo" + i + " ./Examen/Apartado" + i
+ "/examenPFEDAptdo" + i);
p.waitFor();
is = p.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
// Si el comando diff imprime algo es que el fichero ha sido
// modificado
if (br.readLine() != null) {
res = i;
}
}
// Enviamos resultado
conexion.enviaMensaje(res);
}
/**
* Función que devuelve el UVUS del alumno.
*
* @return UVUS
*/
public String getUvus() {
return uvus;
}
/**
* Función que realiza el proceso de ejecución de la herramienta. Recibe el
* UVUS del usuario que realiza la ejecución. Ejecuta el makefile
* correspondiente y genera la respuesta para el alumno.
*
* @throws ClassNotFoundException
* @throws IOException
* @throws InterruptedException
*/
public void corrigeHerramienta() throws ClassNotFoundException,
IOException, InterruptedException {
Runtime runtime;
Process p;
PrintWriter writer;
// Recibimos el nombre del alumno
uvus = conexion.recibeString();
// Introducimos y comprobamos nombre del alumno en BBDD
res = 0;
// Comprobamos conectividad con la base de datos
try {
baseDeDatos.compruebaConex();
res = 1;
} catch (com.mongodb.MongoException e) {
res = 0;
System.out.println("No se pudo conectar con la base de datos");
}
if (res == 1) {
// Eliminamos el resumen del informe de memoria dinámica si existe
runtime = Runtime.getRuntime();
140 – BLOQUE 6. Anexos – Anexo 2. Código fuente
p = runtime.exec("rm ./" + uvus
+ "/PFED/herramienta/ResumenMemoryReport");
p.waitFor();
// Comprobamos que existe el makefile de la herramienta
File herramienta = new File("./" + uvus
+ "/PFED/herramienta/Herramienta");
if (herramienta.exists()) {
// Ejecutamos la herramienta
runtime = Runtime.getRuntime();
p = runtime.exec("make -s -C ./" + uvus
+ "/PFED/herramienta/ -f Herramienta");
p.waitFor();
// Comprobamos que no hay errores de compilación
InputStream e = p.getErrorStream();
InputStreamReader isr = new InputStreamReader(e);
BufferedReader br = new BufferedReader(isr);
br.readLine();
if ((br.readLine()) == null) {
InputStream is = p.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
// Guardamos la salida del comando del makefile
writer = new PrintWriter(
"./" + uvus + "/salidaHerramienta", "UTF-8");
String line;
// Si no imprime nada, o la salida es la esperada la
// ejecución es correcta
while ((line = br.readLine()) != null) {
writer.println(line);
}
writer.close();
// Comprobamos que la salida producida es correcta
runtime = Runtime.getRuntime();
p = runtime.exec("cat ./" + uvus + "/salidaHerramienta");
p.waitFor();
is = p.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
// Si se imprime algo no esperado es que la salida no es
// correcta
boolean control = true;
while ((line = br.readLine()) != null && control) {
if (!line.contains("__")) {
control = false;
}
}
if (control) {
res = 2;
// Comprobamos la gestión de memoria
File fichero = new File("./" + uvus
+ "/PFED/herramienta/ResumenMemoryReport");
// Si el fichero está vacío no hay errores de memoria.
if (fichero.length() == 0) {
res = 3;
}
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
baseDeDatos.publicaNota(uvus, "PFED", 10);
} else {
// Devolvemos confirmación al alumno
conexion.enviaMensaje(res);
// La salida no es correcta.Enviamos informe al alumno
141 – BLOQUE 6. Anexos – Anexo 2. Código fuente
conexion.enviaFichero(new Fichero("./" + uvus
+ "/salidaHerramienta"));
}
} else {
// Caso de no compilar
conexion.enviaMensaje(10);
}
}
}
}
}
142 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Hilo.java /**
* Trabajo final de grado
* Clase hilo. Gestiona la creación y ejecución de hilos en el sistema.
* Cada vez que el servidor recibe una petición de un alumno, crea un
* objeto de tipo Hilo el cual realiza el procedimiento oportuno.
*
* @author Andrés Martínez Gotor
*/
package servidor;
import java.io.IOException;
public class Hilo implements Runnable {
private Thread t;
private String opcion;
private Alumno alumno;
private DataBase baseDeDatos;
private Comunicacion conexion;
/**
* Constructor de la clase. Recibe como parámetros los elementos necesarios
* para la gestión de las peticiones.
*
* @param opcionRec
* Opción elegida por el alumno (registo o ejecución de un
* apartado)
* @param conexionRec
* Conexión con el cliente
* @param baseDeDatosRec
* Base de datos a utilizar
*/
Hilo(String opcionRec, Comunicacion conexionRec, DataBase baseDeDatosRec) {
t = new Thread(this);
opcion = opcionRec;
conexion = conexionRec;
baseDeDatos = baseDeDatosRec;
t.start();
}
/**
* Constructor alternativo. Realiza una acción sin conexión con el cliente.
*
* @param opcionRec
* Opción elegida por el alumno (registo o ejecución de un
* apartado)
* @param baseDeDatosRec
* Base de datos a utilizar
*/
public Hilo(String opcionRec, DataBase baseDeDatosRec) {
t = new Thread(this);
opcion = opcionRec;
baseDeDatos = baseDeDatosRec;
t.start();
}
/**
* Función que realiza cada uno de los hilos creados. Obtiene la opción a
* realizar y llama a la función correspondiente.
*/
public void run() {
System.out.println("Empieza hilo. Opcion: " + opcion);
try {
alumno = new Alumno(conexion, baseDeDatos);
switch (opcion) {
case "registra1":
143 – BLOQUE 6. Anexos – Anexo 2. Código fuente
alumno.registra(1);
conexion.cierraConex();
break;
case "registra2":
alumno.registra(2);
conexion.cierraConex();
break;
case "apartado0":
alumno.corrigeApartado(0);
conexion.cierraConex();
break;
case "apartado1":
alumno.corrigeApartado(1);
conexion.cierraConex();
break;
case "apartado2":
alumno.corrigeApartado(2);
conexion.cierraConex();
break;
case "apartado3":
alumno.corrigeApartado(3);
conexion.cierraConex();
break;
case "compruebaMake":
alumno.compruebaMake();
conexion.cierraConex();
break;
case "herramienta":
alumno.corrigeHerramienta();
conexion.cierraConex();
break;
case "imprime":
baseDeDatos.imprimeNotas();
break;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
144 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Fichero.java /**
* Trabajo final de grado
* Clase fichero. Contiene los atributos y los métodos necesarios para la
transferencia de un fichero.
*
* @author Andrés Martínez Gotor
*/
package servidor;
import java.io.File;
public class Fichero {
private File fichero;
private byte[] bytearray;
int size;
/**
* Contructor de la clase. Almacena el fichero, su tamaño y la secuencia de
* bytes que lo componen.
*
* @param rutaFichero
* ruta del fichero a utilizar
*/
public Fichero(String rutaFichero) {
fichero = new File(rutaFichero);
size = (int) fichero.length();
bytearray = new byte[size];
}
/**
* Constructor por defecto
*/
public Fichero() {
}
/**
* Función que devuelve el fichero utilizado.
*
* @return fichero utilizado
*/
public File getFichero() {
return this.fichero;
}
/**
* Función que devuelve la secuencia de bytes del fichero.
*
* @return cadena de bytes del fichero
*/
public byte[] getByteArray() {
return this.bytearray;
}
/**
* Función que devuelve el tamaño del fichero.
*
* @return tamaño del fichero
*/
public int getTam() {
return this.size;
}
}
145 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Notas.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>PFED</title>
<script src="js/jquery-1.9.0.min.js" type="text/javascript"></script>
<script src="js/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="js/jquery.jqGrid.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="css/ui.jqgrid.css"/>
<link rel="stylesheet" type="text/css" href="css/estilo.css"/>
<script src="fp2.js" type="text/javascript"></script>
<link href="css/smoothness/jquery-ui-1.10.4.custom.css" rel="stylesheet">
<div class="cabecera" >
<div class="titulos" >
<h1> Práctica Final </h1>
<h1> De Estructuras Dinámicas </h1>
<h2> Fundamentos de Programación 2 </h2>
</div>
<div class="images" >
<img src="images/us.gif"/>
<img src="images/dit.gif"/>
</div>
</div>
</head>
<body>
<div id="notas">
<table id="grid"></table>
<div id="pager"></div>
<script>
$("#grid").jqGrid({ //set your grid id
data: mydata, //insert data from the data object we created above
datatype: 'local',
width: 900, //specify width; optional
height: 460,
colNames:['Apellidos','Nombre',
'UVUS','Trabajo','Apartado0','Apartado1','Apartado2','Apartado3'], //define
column names
colModel:[
{name:'Apellidos', index:'Apellidos', width:70},
{name:'Nombre', index:'Nombre', width:50},
{name:'_id', index:'_id', key: true, width:30},
{name:'PFED', index:'PFED', width:30, align:'center'},
{name:'apartado0', index:'apartado0', width:30, align:'center'},
{name:'apartado1', index:'apartado1', width:30, align:'center'},
{name:'apartado2', index:'apartado2', width:30, align:'center'},
{name:'apartado3', index:'apartado3', width:30, align:'center'}
], //define column models
pager: '#pager', //set your pager div id
sortname: 'Apellidos', //the column according to which data is to be sorted;
viewrecords: true, //if true, displays the total number of records, etc.
sortorder: "asc", //sort order; optional
caption:"Examen FP2" //title of grid
});
</script>
</div>
<div class="footer" >
<p> Trabajo Final de Grado. Andrés Martínez Gotor. </p>
</div>
</body>
</html>
146 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Control de plagio
Main.java package detector;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException{
Funciones funciones = new Funciones();
final File folder = new File("./sim/PFEDExamen");
ArrayList<String> lista = funciones.obtieneAlumnos(folder);
PrintWriter informe=new PrintWriter("informePlagio.txt","UTF-8");
for (int i=0; i<lista.size();i++){
funciones.compruebaPlagio(lista.get(i),informe);
}
informe.close();
}
}
147 – BLOQUE 6. Anexos – Anexo 2. Código fuente
Funciones.java package detector;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
public class Funciones {
private ArrayList<String> lista;
private ArrayList<String> apartado;
public Funciones (){
lista= new ArrayList<String>();
apartado = new ArrayList<String>();
apartado.add("Apartado0");
apartado.add("Apartado1");
apartado.add("Apartado2");
apartado.add("Apartado3");
}
public ArrayList<String> obtieneAlumnos(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
if(!fileEntry.getName().equals("Examen")){
lista.add(fileEntry.getName());
}
}
}
return lista;
}
public void compruebaPlagio(String alumno, PrintWriter informe) throws
IOException{
Process p;
informe.println("--------------- Evaluando alumno:
"+alumno.toUpperCase()+" ---------------");
for (int i =0; i<apartado.size();i++){
informe.println("--------------- "+apartado.get(i)+" ----
-----------");
for (int j=0; j<lista.size();j++){
if(!alumno.equals(lista.get(j))){
p=Runtime.getRuntime().exec("./sim/sim_c.exe -e -p -S -t 30 "
+ "./sim/PFEDExamen/" + alumno
+"/Examen/"+apartado.get(i)+"/*.c "
+ "/ ./sim/PFEDExamen/" + lista.get(j)
+"/Examen/"+apartado.get(i)+"/*.c");
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line =br.readLine();
boolean control=true; // Para imprimir solo una vez el nombre si
es necesario
while(line!=null){
if(!line.contains("File") && !line.contains("tokens"))
if(!line.isEmpty()){
if(control){
informe.println("Comparación "+ alumno + " - "+
lista.get(j));
control=false;
}
String cadena = "./sim/PFEDExamen/"+alumno+"/Examen/";
String cadena2 =
"./sim/PFEDExamen/"+lista.get(j)+"/Examen/";
String line2 = line.replaceAll(cadena, "");
148 – BLOQUE 6. Anexos – Anexo 2. Código fuente
String line3 = line2.replaceAll(cadena2, "");
informe.println(line3);
informe.flush();
}
line=br.readLine();
}
}
}
}
informe.println("");
}
}