• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Xesthproyecto
 

Xesthproyecto

on

  • 232 views

 

Statistics

Views

Total Views
232
Views on SlideShare
232
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Xesthproyecto Xesthproyecto Document Transcript

    • Facultad de Inform´tica de la Universidad de A Coru˜ a a n Departamento de Tecnolog´ de la Informaci´n y las Comunicaciones ıas o PROYECTO DE FIN DE CARRERA ´ ´ INGENIER´ TECNICA INFORMATICA DE GESTION IA ´ Dise˜ o e Implementaci´n de una Aplicaci´n Web Java EE n o o con Arquitectura MVC Destinada a Gestionar las Actividades de un Hotel Alumno: Sergio Pad´ Varela ın Director: Carlos Alberto Pan Berm´ dez u Fecha: 29 de septiembre de 2009
    • A mis padres, mi hermano, mis abuelos y a toda mi familia, por su apoyo y ayuda incondicional. A todos mis amigos por los buenos momentos que me han regalado. Y a mi novia por todo el cari˜o, apoyo y animo que me ha dado en todo momento. A todos n ´ ellos, much´simas gracias. ı Sergio Pad´n Varela ı 3
    • 5 ´ Dr. Carlos Alberto Pan Bermudez Profesor de la Faculdad de Inform´tica de la Coru˜a a n Departamento de Tecnolog´ de la Informaci´n y las Comunicaciones ıas o Universidad de A Coru˜a n CERTIFICA: Que la memoria titulada “Dise˜o e Implementaci´n de una Aplicaci´n n o o Web Java EE con Arquitectura MVC Destinada a Gestionar las Actividades de un Hotel” ha sido realizada por Sergio Pad´ Varela bajo mi direcci´n y constituye su Proyecto ın o de Fin de Carrera de Ingenier´ T´cnica Inform´tica de Gesti´n. ıa e a o En A Coru˜a, a 25 de septiembre de 2009 n ´ Dr. Carlos Alberto Pan Bermudez Director del proyecto
    • 7 Resumen: El proyecto realizado consiste en desarrollar una Aplicaci´n Web para la gesti´n de o o las reservas de un hotel o similar. Tambi´n hay que desarrollar todo lo necesario para la e realizaci´n de reservas, incluyendo entre otros la gesti´n de clientes y usuarios de la web, o o las habitaciones, y los pagos de las mismas. Adem´s tambi´n se desarrolla un complejo sistema de ofertas, donde se permite crear a e ofertas que puedan ser incompatibles unas con otras y basadas en reglas de aplicaci´n, o altamente configurables para especificar el contexto al cu´l se le puede aplicar dicha oferta. a Estas luego son utilizadas din´micamente a la hora de realizar la factura que tiene que a abonar el cliente, en donde se calcula el conjunto de ofertas compatibles entre s´ que mayor ı descuento proporcionan sobre la factura. La Aplicaci´n distingue tres roles principales: el usuario/cliente (de ahora en adelante el o cliente), el recepcionista y el administrador. Cada uno puede realizar una serie operaciones sobre la aplicaci´n. o El cliente puede realizar reservas, consultar las ya realizadas y pagarlas o cancelarlas, ver disponibilidad de habitaciones, y todas las operaciones relacionadas con altas, bajas o actualizaciones de su perfil web. Por otro lado el recepcionista puede gestionar los clientes, d´ndolos de alta, de baja, a actualizar sus perfiles o realizar reservas a su nombre. Para todo ello el recepcionista puede buscar a los clientes por uno o m´s par´metros. Tambi´n tiene la posibilidad de cobrar a a e una reserva a un cliente o cancelarla, entre otras cosas. El administrador es el usuario de la aplicaci´n que m´s privilegios tiene. Este puede o a a˜adir habitaciones, modificar precios y mantener todo el sistema de ofertas. Creando n nuevas ofertas, modific´ndolas, public´ndolas o d´ndolas de baja. Este apartado es muy a a a delicado debido a las relaciones de incompatibilidad entre ofertas y a las reglas que estas utilizan para saber si se pueden aplicar en determinados contextos.
    • 9 Lista de palabras clave: Aplicaci´n Web, Java, J2EE, MVC, Struts, Apache Tomcat, MySQL, HTML, XML, o CSS, JSP, JSPX, JSTL, Tiles, JDBC, Data Access Object (DAO), Value Object (VO), Hotel, Reserva, Facturaci´n, Ofertas, Reglas, Incompatibilidades. o
    • Agradecimientos1 A D. Carlos Alberto Pan Berm´dez (Profesor de la Facultad de Inform´tica, Universidad u a de A Coru˜a), por la orientaci´n durante la realizaci´n del proyecto, as´ como su ayuda a la n o o ı hora de resolver problemas puntuales durante el dise˜o e implementaci´n de la aplicaci´n. n o o A D˜a. Mar´ Luisa Carpente Rodr´ n ıa ıguez (Profesor de la Facultad de Inform´tica, Unia versidad de A Coru˜a), por su ayuda a la hora de resolver de forma pr´ctica el grafo de n a incompatibilidades entre las ofertas. 1 En orden alfab´tico e 11
    • ´ Indice general Introducci´n o XIII 1. Herramientas y tecnolog´ utilizadas ıas 1 1.1. Herramientas y tecnolog´ para el Dise˜o . . . . . . . . . . . . . . . . . . . ıas n 1 1.2. Herramientas y tecnolog´ para la Implementaci´n . . . . . . . . . . . . . . ıas o 2 1.3. Herramientas y tecnolog´ para la Documentaci´n . . . . . . . . . . . . . . 10 ıas o 2. Estado actual de las tecnolog´ utilizadas ıas 13 3. Estudio de viabilidad 17 4. Introducci´n al desarrollo realizado o 21 4.1. El Proceso Unificado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.2. El Proceso Unificado en este Proyecto . . . . . . . . . . . . . . . . . . . . . 24 5. Requisitos del Sistema 29 5.1. Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 o 5.2. Actores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 5.3. Casos de Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 i
    • ´ Indice general ii 5.3.1. Gesti´n de Usuarios Web . . . . . . . . . . . . . . . . . . . . . . . . 34 o 5.3.2. Gesti´n de Reservas Web . . . . . . . . . . . . . . . . . . . . . . . . 40 o 5.3.3. Gesti´n de Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 o 5.3.4. Gesti´n de Reservas . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 o 5.3.5. Gesti´n de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . . . 60 o 5.3.6. Gesti´n de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 o 5.4. Modelo de Casos de Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.4.1. Gesti´n de Usuarios Web . . . . . . . . . . . . . . . . . . . . . . . . 78 o 5.4.2. Gesti´n de Reservas Web . . . . . . . . . . . . . . . . . . . . . . . . 79 o 5.4.3. Gesti´n de Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 o 5.4.4. Gesti´n de Reservas . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 o 5.4.5. Gesti´n de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . . . 82 o 5.4.6. Gesti´n de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 o 6. Dise˜ o de la aplicaci´n n o 85 6.1. Arquitectura General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 6.2. Capa de la Vista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 6.2.1. Hojas de Estilo - CSS . . . . . . . . . . . . . . . . . . . . . . . . . . 88 6.2.2. P´ginas JSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 a 6.2.3. ActionForms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 6.2.4. Internacionalizaci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 o 6.2.5. ApplicationObjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 6.3. Capa del Controlador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
    • ´ Indice general iii 6.3.1. Patr´n Front Controller . . . . . . . . . . . . . . . . . . . . . . . . . 94 o 6.3.2. Patr´n Chain of Responsability . . . . . . . . . . . . . . . . . . . . . 96 o 6.3.3. Acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 6.3.4. Clases de Utilidad y Soporte a Acciones . . . . . . . . . . . . . . . . 99 6.4. Arquitectura del Modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 6.4.1. Persistencia de los Datos . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.4.2. Patrones Utilizados en el Modelo . . . . . . . . . . . . . . . . . . . . 111 6.4.3. Capa de Acceso a la Base de Datos . . . . . . . . . . . . . . . . . . . 117 6.4.4. Descripci´n de los Subsistemas . . . . . . . . . . . . . . . . . . . . . 131 o 6.4.5. Sistema de Soporte - Modelo de Ofertas . . . . . . . . . . . . . . . . 166 7. Implementaci´n o 183 7.1. Detalles Espec´ ıficos de la Implementaci´n . . . . . . . . . . . . . . . . . . . 183 o 7.2. Implementaci´n de las Base de Datos . . . . . . . . . . . . . . . . . . . . . . 185 o 7.2.1. Implementaci´n de la Base de Datos General . . . . . . . . . . . . . 185 o 7.2.2. Implementaci´n de la Base de Datos de Ofertas . . . . . . . . . . . . 190 o 7.3. Implementaciones del Sistema de Ofertas . . . . . . . . . . . . . . . . . . . 192 7.4. Software Necesario para Desplegar la Aplicaci´n . . . . . . . . . . . . . . . 204 o 7.4.1. Instalaci´n y Configuraci´n del Software Necesario . . . . . . . . . . 204 o o 7.5. Organizaci´n de los Directorios del Proyecto . . . . . . . . . . . . . . . . . . 208 o 7.6. Instrucciones de Compilaci´n y Despliegue . . . . . . . . . . . . . . . . . . . 209 o 8. Pruebas 211
    • ´ Indice general iv 9. Planificaci´n y Evaluaci´n de Costes o o 213 10.Conclusiones y Futuras L´ ıneas de Trabajo 217 A. Manuales para la Utilizaci´n de la Aplicaci´n o o 221 A.1. Manual Com´n a Todos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 u A.2. Manual Espec´ ıfico para el Usuario . . . . . . . . . . . . . . . . . . . . . . . 225 A.3. Manual Espec´ ıfico para el Recepcionista . . . . . . . . . . . . . . . . . . . . 231 A.4. Manual Espec´ ıfico para el Administrador B. Licencia del Proyecto - GPLv3 . . . . . . . . . . . . . . . . . . . 239 251 B.1. General Public License (Version 3) . . . . . . . . . . . . . . . . . . . . . . . 251
    • ´ Indice de figuras 4.1. Gr´fico del Proceso Unificado . . . . . . . . . . . . . . . . . . . . . . . . . . 22 a 5.1. CU: Gesti´n de Usuarios Web . . . . . . . . . . . . . . . . . . . . . . . . . . 78 o 5.2. CU: Gesti´n de Reservas Web . . . . . . . . . . . . . . . . . . . . . . . . . . 79 o 5.3. CU: Gesti´n de Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 o 5.4. CU: Gesti´n de Reservas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 o 5.5. CU: Gesti´n de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 82 o 5.6. CU: Gesti´n de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 o 6.1. MVC - Arquitectura General Del Sistema . . . . . . . . . . . . . . . . . . . 86 6.2. Capa Vista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 6.3. Plantilla Ventana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 6.4. Resultado Final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 6.5. Patr´n Front Controller General . . . . . . . . . . . . . . . . . . . . . . . . 95 o 6.6. Paquetes - Distribucion de Acciones . . . . . . . . . . . . . . . . . . . . . . 99 6.7. Diagrama Aplicaci´n de Front Controller o . . . . . . . . . . . . . . . . . . . 100 6.8. Diagrama Entidad Relaci´n - General . . . . . . . . . . . . . . . . . . . . . 107 o v
    • ´ Indice de figuras vi 6.9. Modelo Relacional - General . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 6.10. Diagrama Entidad Relaci´n - Ofertas . . . . . . . . . . . . . . . . . . . . . . 110 o 6.11. Modelo Relacional - Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 6.12. Diagrama de Value Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 6.13. Diagrama de Data Access Object . . . . . . . . . . . . . . . . . . . . . . . . 113 6.14. Diagrama de Data Access Object Utilizado . . . . . . . . . . . . . . . . . . 114 6.15. Diagrama de Session Facade y Business Delegate . . . . . . . . . . . . . . . 116 6.16. Diagrama del Procesador de Acciones . . . . . . . . . . . . . . . . . . . . . 117 6.17. Estructura de los paquetes DAO y VO . . . . . . . . . . . . . . . . . . . . . 118 6.18. Diagrama General de los DAO . . . . . . . . . . . . . . . . . . . . . . . . . 118 6.19. Diagrama del Paquete ’persona’ . . . . . . . . . . . . . . . . . . . . . . . . . 119 6.20. Diagrama del Paquete ’tipohabitacion’ . . . . . . . . . . . . . . . . . . . . . 120 6.21. Diagrama del Paquete ’habitacion’ . . . . . . . . . . . . . . . . . . . . . . . 121 6.22. Diagrama del Paquete ’esdetipo’ . . . . . . . . . . . . . . . . . . . . . . . . 122 6.23. Diagrama del Paquete ’incidencia’ . . . . . . . . . . . . . . . . . . . . . . . 123 6.24. Diagrama del Paquete ’lineadereserva’ . . . . . . . . . . . . . . . . . . . . . 124 6.25. Diagrama del Paquete ’reserva’ . . . . . . . . . . . . . . . . . . . . . . . . . 125 6.26. Diagrama del Paquete ’factura’ . . . . . . . . . . . . . . . . . . . . . . . . . 126 6.27. Diagrama del Paquete ’tipooferta’ . . . . . . . . . . . . . . . . . . . . . . . 127 6.28. Diagrama del Paquete ’oferta’ . . . . . . . . . . . . . . . . . . . . . . . . . . 128 6.29. Diagrama del Paquete ’aplicablea’ . . . . . . . . . . . . . . . . . . . . . . . 129 6.30. Diagrama del Paquete ’incompatiblecon’ . . . . . . . . . . . . . . . . . . . . 130
    • ´ Indice de figuras vii 6.31. Diagrama Simple de Gesti´n de Usuarios o . . . . . . . . . . . . . . . . . . . 132 6.32. Actions y Exceptions de Gesti´n de Usuarios . . . . . . . . . . . . . . . . . 132 o 6.33. Diagrama Simple de Gesti´n de Clientes . . . . . . . . . . . . . . . . . . . . 135 o 6.34. Actions y Exceptions de Gesti´n de Clientes . . . . . . . . . . . . . . . . . . 136 o 6.35. Diagrama Simple de Gesti´n de Reservas o . . . . . . . . . . . . . . . . . . . 139 6.36. Actions y Exceptions de Gesti´n de Reservas . . . . . . . . . . . . . . . . . 140 o 6.37. Diagrama Simple de Gesti´n de Habitaciones . . . . . . . . . . . . . . . . . 145 o 6.38. Actions de Gesti´n de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . 146 o 6.39. Diagrama Simple de Gesti´n de Tipos de Ofertas . . . . . . . . . . . . . . . 151 o 6.40. Actions de Gesti´n de Tipos de Ofertas . . . . . . . . . . . . . . . . . . . . 152 o 6.41. Diagrama Simple de Gesti´n de Ofertas . . . . . . . . . . . . . . . . . . . . 156 o 6.42. Actions de Gesti´n de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . 157 o 6.43. Diagrama de la Interfaz Ofertable . . . . . . . . . . . . . . . . . . . . . . . . 160 6.44. Diagrama Simple de Gesti´n de Facturas . . . . . . . . . . . . . . . . . . . . 162 o 6.45. Actions y Exceptions de Gesti´n de Facturas . . . . . . . . . . . . . . . . . 163 o 6.46. Diagrama del Sistema de Reglas . . . . . . . . . . . . . . . . . . . . . . . . 173 6.47. Diagrama de clase BestSetOfOffers . . . . . . . . . . . . . . . . . . . . . . . 176 6.48. Diagrama de las Clases Calculadoras . . . . . . . . . . . . . . . . . . . . . . 178 6.49. Diagrama Simple del Sistema de Ofertas . . . . . . . . . . . . . . . . . . . . 181 6.50. Diagrama Secuencia de la Acci´n de Calcular . . . . . . . . . . . . . . . . . 182 o 9.1. Planificaci´n - Diagrama de Gantt . . . . . . . . . . . . . . . . . . . . . . . 215 o 10.1. Gesti´n de Reservas de Otra Aplicaci´n . . . . . . . . . . . . . . . . . . . . 218 o o
    • ´ Indice de figuras viii A.1. P´gina Principal del Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 a A.2. P´gina Registro de Nuevo Usuario . . . . . . . . . . . . . . . . . . . . . . . 222 a A.3. P´gina Autentificaci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 a o A.4. P´gina Principal del Usuario . . . . . . . . . . . . . . . . . . . . . . . . . . 225 a A.5. P´gina de Aviso al Darse de Baja . . . . . . . . . . . . . . . . . . . . . . . . 226 a A.6. P´gina para Realizar una Nueva Reserva . . . . . . . . . . . . . . . . . . . . 227 a A.7. P´gina para Listar las Reservas . . . . . . . . . . . . . . . . . . . . . . . . . 228 a A.8. P´gina para Modificar una Reserva . . . . . . . . . . . . . . . . . . . . . . . 229 a A.9. P´gina para Mostrar el Borrador de una Factura . . . . . . . . . . . . . . . 229 a A.10.P´gina para Mostrar una Factura Pagada . . . . . . . . . . . . . . . . . . . 230 a A.11.P´gina Principal del Recepcionista . . . . . . . . . . . . . . . . . . . . . . . 231 a A.12.P´gina para Listar las Habitaciones para el Recpecionista . . . . . . . . . . 232 a A.13.P´gina para Mostrar los Datos de un Tipo de Habitaci´n . . . . . . . . . . 233 a o A.14.P´gina para Dar de Alta un Nuevo Cliente . . . . . . . . . . . . . . . . . . 234 a A.15.P´gina para Buscar Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 a A.16.P´gina para Listar los Clientes Buscados . . . . . . . . . . . . . . . . . . . . 235 a A.17.P´gina Principal del Recepcionista Despu´s de Seleccionar Cliente . . . . . 236 a e A.18.P´gina Principal del Administrador . . . . . . . . . . . . . . . . . . . . . . . 239 a A.19.P´gina para Crear una Nueva Oferta . . . . . . . . . . . . . . . . . . . . . . 240 a A.20.P´gina para Crear una Nueva Oferta (Rellenada) . . . . . . . . . . . . . . . 241 a A.21.P´gina para Crear un Nuevo Tipo de Oferta . . . . . . . . . . . . . . . . . . 243 a A.22.P´gina para Listar las Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . 244 a
    • ´ Indice de figuras ix A.23.P´gina para Realizar Operaciones con las Ofertas . . . . . . . . . . . . . . . 244 a A.24.P´gina para Realizar Operaciones con los Tipos de Ofertas . . . . . . . . . 245 a A.25.P´gina para Dar de Alta una Habitaci´n . . . . . . . . . . . . . . . . . . . . 246 a o A.26.P´gina para Crear un Nuevo Tipo de Habitaci´n . . . . . . . . . . . . . . . 246 a o A.27.P´gina para Listar las Habitaciones para el Administrador . . . . . . . . . . 247 a A.28.P´gina para Consultar/Modificar los Datos de una Habitaci´n a o . . . . . . . 248 A.29.P´gina para Consultar/Modificar los Datos de un Tipo de Habitaci´n . . . 248 a o A.30.P´gina para Listar las Incidencias de una Habitaci´n . . . . . . . . . . . . . 249 a o A.31.P´gina para Registrar una Incidencia de una Habitaci´n . . . . . . . . . . . 250 a o
    • ´ Indice de cuadros 3.1. Tabla de costes para estudio de viabilidad . . . . . . . . . . . . . . . . . . . 18 9.1. Planificaci´n - Tabla de Tareas . . . . . . . . . . . . . . . . . . . . . . . . . 214 o xi
    • Introducci´n o Determinaci´n de la situaci´n actual o o En la actualidad el turismo es una fuente indiscutible de ingresos para muchas zonas, e Internet llega casi a todos los rincones del mundo, por eso es una de las mejores formas de dar a conocer negocios de todo tipo. Es especialmente util a la hora de ofrecer servicios ´ de alojamiento, y ocio entre otros. Cada d´ m´s personas planean sus vacaciones a trav´s de Internet, por lo que no s´lo ıa a e o es bueno dar a conocer los servicios que se prestan, sin´ tambi´n dar la oportunidad de o e poder contratar esos servicios est´ donde est´ el cliente. e e Hoy en d´ muchas peque˜as empresas hoteleras a´n siguen registrando sus reservas ıa n u manualmente en un libro para tal efecto. Estas se producen normalmente por tel´fono, e no ofreciendo pr´cticamente ninguna garant´ de que la reserva vaya a ser pagada, los a ıa responsables del establecimiento dieron su palabra al cliente que llam´ y esa estancia o puede que quede sin ocupar, con las posibles p´rdidas que ello pueda conllevar. Adem´s e a normalmente no tienen un sitio web que puedan usar para promocionarse, lo que implica que s´lo se pueden dar a conocer a trav´s de anuncios o similares y esto supone un gasto o e adicional para la empresa. Las grandes firmas de hoteles y multinacionales no tienen todos esos problemas. La mayor´ permite que se reserven habitaciones a trav´s de su sitio web y pide que se abone ıa e el pago de dicha reserva, as´ se aseguran que esta se va llevar a cabo. Las que no permiten ı xiii
    • xiv hacer el pago en el momento de la realizaci´n de la reserva tampoco pierden demasiado, o ya que la p´rdida de una estancia es compensada por la multitud que se hacen efectivas e debido a sus vol´menes de negocio. Estas empresas tampoco se tienen que preocupar u demasiado por la publicidad, ya que pueden permitirse hacer campa˜as publicitarias por n todo el mundo, y todas tienen sus sitios web actualizados. Alcance y objetivos La forma tradicional de gestionar un hotel, es tediosa y a veces incluso dif´ de llevar a ıcil cabo si el volumen de trabajo del hotel es elevado o si hay muchas habitaciones y servicios de los cuales hay que mantener actualizados sus datos. Este proyecto surge para ayudar a simplificar y facilitar las tareas propias de la gesti´n o de un hotel, comenzando por desarrollar un sistema a trav´s del cual se puedan realizar e reservas y generar facturas, as´ como gestionar las habitaciones, etc. Para esto se desarrolla ı una Aplicaci´n Web, que permitir´ hacer reservas on-line del mismo modo que tambi´n o a e se podr´ gestionar el hotel en su totalidad, f´cil y c´modamente. a a o Se pretende entre otras cosas que este proyecto sea f´cilmente ampliable, de forma que, a a medida que vayan surgiendo necesidades distintas dentro de la gesti´n de un hotel, se o pueda dar una soluci´n f´cil, r´pida y lo m´s elegante posible. Adem´s se desarrolla de o a a a a forma que se pueda integrar de forma c´moda la gesti´n del hotel y la gesti´n del sitio o o o web, ya que actualmente en el ´mbito de los hoteles hay la necesidad de darlos a conocer a a un mayor p´blico para ampliar el mercado. u Para comenzar se definen los usuarios que van a interactuar con la aplicaci´n. El Cliente, o el Recepcionista y el Administrador ser´n los usuarios principales, pero no los unicos, ya a ´ que la aplicaci´n necesitar´ tambi´n tener como actor de soporte alguna entidad financiera o a e contra la cual se realizar´n los pagos de las reservas. a
    • xv Cualquier usuario que entre en el portal del hotel puede consultar nuevas noticia acerca del hotel, la ofertas que actualmente ofrece el establecimiento y diversos datos referentes al hotel: ubicaci´n, fotograf´ etc. o ıas, El usuario tendr´ la posibilidad de crearse una cuenta en el portal web del hotel, con la a cual podr´ realizar distintas acciones. El usuario que est´ registrado podr´ modificar sus a e a datos personales en cualquier momento o darse de baja cuando lo desee. Tambi´n tendr´ la e a posibilidad de realizar tantas reservas como quiera y luego podr´ pasar a administrarlas, a pudiendo as´ cancelar o modificar las reservas efectuadas, o comprobar la factura para ver ı cu´nto tendr´ que pagar. Esta factura se calcula de forma din´mica aplicando el conjunto a ıa a de ofertas que descuenten la mayor cantidad de dinero a la factura. Una vez vista la fatura podr´ pagarla en ese preciso momento, a partir del cual la reserva quedar´ hecha. a a A partir del momento en el que un usuario registrado paga su primera reserva, ya se puede considerar como cliente del hotel. Por otro lado el recepcionista del hotel puede realizar tambi´n reservas para un cliente. e En primer lugar se le da la opci´n de actualizar sus datos personales. Tambi´n puede o e buscar a un cliente en la base de datos por varios criterios, nombre, apellidos, etc. Si el cliente no est´ registrado, se le da la oportunidad de darlo de alta en el sistema, y si lo a est´ se puede tambi´n modificar su perfil. A continuaci´n se le permite realizar la reserva a e o que el cliente le pueda pedir. Y cuando el cliente pague la reserva el empleado de recepci´n o del hotel podr´ marcar la factura como pagada en la aplicaci´n. a o Asimismo, puede consultar las reservas de un cliente, las habitaciones, precios y otras consultas generales acerca del hotel. El administrador de la aplicaci´n y del hotel tiene como actividades principales en o el sistema gestionar las distintas partes del mismo. Puede crear habitaciones, consultar y modificar sus datos, tambi´n tiene la posibilidad de hacer lo mismo con los tipos de e habitaciones que son los que en realidad definen los precios y condiciones que tienen las mismas.
    • xvi Otra de las operaciones que puede realizar el administrador es la creaci´n y publicaci´n o o de ofertas. Cuando el administrador crea una oferta, ademas de cubrir de qu´ fecha a e qu´ fecha la oferta ser´ aplicable, tambi´n debe especificar la regla que se debe cumplir e a e con respecto al contexto en el cual se har´ efectiva la oferta, de esta forma se podr´ definir a a m´s concretamente los par´metros que se deben de cumplir para que la oferta se pueda a a aplicar. Mediante el uso de reglas se podr´ definir, por ejemplo, que una oferta s´lo se a o pueda aplicar a los clientes de un determinado pa´ que hayan nacido antes de una fecha ıs determinada y que paguen la reserva antes de un d´ fijado. ıa Estas reglas podr´n definirse a trav´s del lenguaje natural, siguiendo simplemente unas a e condiciones en la escritura de las mismas, como que las diferentes partes en las que se divide una regla est´n separadas utilizando unos caracteres especiales. Por ejemplo, una posible e regla para decir que solo se puede aplicar a personas de Espa˜a que nacieran antes del 20 de n Octubre de 1980 ser´ la siguiente: “PersonFrom:Espa˜a&&PersonBornBefore:20,10,1980” ıa n El sistema de reglas desarrollado es altamente configurable de forma que se pueden a˜adir nuevas reglas al sistema sin tener que alterar nada de lo que ya est´ hecho. As´ de n a ı este modo se podr´ definir en caso necesario, condiciones m´s elaboradas, como por ıan a ejemplo, que s´lo se pudiese aplicar a aquellas personas que desde la apertura del hotel o hayan gastado en ´l m´s de una cantidad de dinero. e a La internacionalizaci´n de la aplicaci´n es algo fundamental en este caso ya que al o o tratarse de un hotel es imprescindible especificarlo todo en varios idiomas y as´ llegar ı mejor a clientes extranjeros. La aplicaci´n web tendr´ traducci´nes a Espa˜ol, Gallego e o a o n Ingl´s, y ser´ muy sencillo a˜adir nuevas traducciones en un futuro, de igual forma tambi´n e a n e estar´n internacionalizadas las fechas y los n´meros, pero se dejan sin internacionalizar a u los precios ya que todas las transacciones se har´n y se calcular´n en Euros. a a
    • xvii Estructura de la memoria Esta memoria se ha estructurado en 10 cap´ ıtulos en los cuales se explican los diferentes temas a tener en cuenta en la realizaci´n de un proyecto software. o Cap´ ıtulo 1. En este cap´ ıtulo se detallan de forma breve todas las tecnolog´ empleadas ıas en el desarrollo y documentaci´n del proyecto, desde las herramientas utilizadas para o realizar el c´digo fuente de la aplicaci´n, hasta las tecnolog´ empleadas para que esta o o ıas funcionase correctamente en el momento del despliege final de la misma. Cap´ ıtulo 2. En este apartado se explica el estado de las tecnolog´ utilizadas en la ıas actualidad, as´ como la diferencia con otras tecnolog´ disponibles en el mercado, y el ı ıas porqu´ se utilizaron unas y no otras. Para esta eleci´n estuvo muy presente la idea de que e o la aplicaci´n final deber´ poder licenciarse como software libre por lo que las licencias de o ıa algunas tecnolog´ impidieron su uso. ıas Cap´ ıtulo 3. Se estudia en este cap´ ıtulo la viabilidad del desarrollo de la aplicaci´n que o se realizar´. En este estudio se tiene en cuenta desde el tiempo estimado que se emplear´ en a a su desarrollo como el coste este conllevar´, adem´s de otras cuestiones como la posible a a comercializaci´n del producto una vez terminado. o Cap´ ıtulo 4. En este cap´ ıtulo se indica la metodolog´ que se sigue en el desarrollo del ıa proyecto. En este caso se detallan las caracter´ ısticas del Proceso Unificado y sus diferentes fases en el ciclo de desarrollo de la aplicaci´n. o Adem´s se explica detalladamente lo que se hizo en cada una de estas fases en el proyecto, a indicando exactamente en qu´ momento, iteraci´n, de la fase del Proceso Unificado se e o realiz´. o
    • xviii Cap´ ıtulo 5. Se detallan en este cap´ ıtulo todos los requisitos que regir´n el desarrollo a del proyecto. En un primer lugar se analizar´n textualmente y de forma general las funa cionalidades que deber´ contemplar la aplicaci´n, que luego ser´n detalladas exactamente a o a en un modelo de casos de uso. Este modelo de casos de uso se explicar´ dividi´ndolo en subconjuntos de casos de uso a e relacionados, y dentro de cada subconjunto se detallar´ cada uno de los casos de uso por a separado y se mostrar´ un diagrama de casos de uso para ver como se relacionan estos a con los actores que interactuar´n con la aplicaci´n. a o Cap´ ıtulo 6. Este cap´ ıtulo junto con el anterior son los dos cap´ ıtulos fundamentales en el desarrollo del proyecto, ya que en este se detalla todo el dise˜o del sistema final. n Se explican en este apartado las diferentes capas en las que se divide el sistema, b´sia camente se describe la arquitectura Modelo-Vista-Controlador utilizada. Despu´s de una e introducci´n al dise˜o realizado se detalla el funcionamiento y el dise˜o de cada una de o n n las capas por separado. En la capa modelo es donde se realiza especial incapi´ ya que es donde estar´ situae a da toda la l´gica de negocio del sistema, donde realmente se implementar´n los casos de o a uso especificados en el modelo de casos de uso. Para desglosar esta capa, se realiza una separaci´n en subsistemas, se puede identificar claramente cada uno de ellos con un subo conjunto de casos de uso y a continuaci´n se explica el dise˜o utilizado en estos subsistemas o n acompa˜andolos en todo momento de los diagramas UML correspondientes. n´ Para terminar, pero ni mucho menos importante, se explica en detalle el sistema de soporte de las ofertas realizado para resolver, de forma aislada del resto del modelo, las cuestiones referente al comportamiento de las ofertas. Para detallar este comportamiento se comienza con una explicaci´n textual de c´mo deben operar e interacturar entre ellas y a o o continuaci´n se hace un an´lisis m´s formal apoy´ndose en un grafo de incompatibilidades o a a a y su resoluci´n, realizado expresamente para solventar las cuestiones m´s complejas del o a
    • xix sistema. Por otro lado se explica tambi´n el funcionamiento del sistema de reglas y el e lenguaje utilizado para definirlas, siendo las reglas las que rigen la aplicabilidad de las ofertas dependiendo del contexto. Cap´ ıtulo 7. En este apartado se describe como se ha realizado la implementaci´n de o la aplicaci´n, as´ como el software utilizado para su despliegue y configuraci´n. Adem´s o ı o a tambi´n se expondr´n problemas surgidos durante la implementaci´n del proyecto y sus e a o soluciones. Cap´ ıtulo 8. Este cap´ ıtulo de la memoria describe las diferentes pruebas realizadas para probar el correcto funcionamiento de la aplicaci´n. Entre las pruebas hechas destacan las o pruebas de unidad, aunque no menos importantes son las pruebas de funcionalidad para chequear que la aplicaci´n cumpliese con todos los requisitos de funcionalidad requeridos o al inicio del proyecto. Cap´ ıtulo 9. En este cap´ ıtulo se establece la planificaci´n de tiempo y costes para la o realizaci´n del proyecto, ilustrado todo con un diagrama de Gantt. o Cap´ ıtulo 10. Este es el cap´ ıtulo d´nde se comentan las impresiones acerca del proyecto, o as´ como las conclusiones sobre los conocimientos adquiridos y futuras posibles modificaı ciones sobre este proyecto.
    • Cap´ ıtulo 1 Herramientas y tecnolog´ ıas utilizadas Para la realizaci´n de este proyecto se utilizaron distintas herramientas y tecnolog´ o ıas, desde el dise˜o y la implementaci´n, hasta la documentaci´n del sistema. n o o 1.1. Herramientas y tecnolog´ para el Dise˜ o ıas n ArgoUML Es una aplicaci´n para realizar diagramas UML escrita en Java y publicada o bajo la Licencia BSD open source. Dado que es una aplicaci´n Java, est´ disponible en o a cualquier plataforma soportada por Java. Aunque la interfaz gr´fica no es lo mejor del a mercado, la potencia para realizar diagramas y exportarlo a la mayor´ de los formatos ıa que se puedan querer, hace de esta aplicaci´n una herramienta de gran ayuda a la hora de o realizar los diagramas para desarrollar una aplicaci´n. o Adem´s esta aplicaci´n permite realizar ingenier´ directa de diagramas UML a c´digo, a o ıa o pero no s´lo a c´digo Java, sin´ tambi´n a otros lenguajes como C# o PHP. Tambi´n o o o e e permite la realizaci´n de ingenier´ inversa, generando un modelo a partir de c´digo fuente. o ıa o Esto es muy util a la hora de documentar un proyecto, ya que de esta forma se asegura ´ 1
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 2 de que no se olvida de nada, especialmente cuando se crea un modelo de clases detallado, donde muy a menudo se puede olvidar de alg´n m´todo, atributo, etc. u e DIA Es una aplicaci´n gr´fica de prop´sito general para la creaci´n de diagramas, desao a o o rrollada como parte del proyecto GNOME. Est´ concebido de forma modular, con difea rentes paquetes de formas para diferentes necesidades. Dia est´ dise˜ado como un sustituto de la aplicaci´n comercial Visio de Microsoft. Se a n o puede utilizar para dibujar diferentes tipos de diagramas. Actualmente se incluyen diagramas entidad-relaci´n, diagramas UML, diagramas de flujo, diagramas de redes, diagramas o de circuitos el´ctricos, etc. Nuevas formas pueden ser f´cilmente agregadas, dibuj´ndolas e a a con un subconjunto de SVG e incluy´ndolas en un archivo XML. e El formato para leer y almacenar gr´ficos es XML (comprimido con gzip, para ahorrar a espacio). Pero lo interesante, al igual que con ArgoUML es que puede producir salida en m´ltiples formatos como: EPS, SVG, PNG, etc. Y al igual que ArgoUML, Dia, gracias al u paquete ‘dia2code‘, puede generar el esqueleto del c´digo a escribir a partir de un diagrama o UML. 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o Java EE Java Platform, Enterprise Edition, tambi´n conocida como J2EE es un cone junto de especificaciones Java definidas para la construcci´n de aplicaciones empresariales. o Estas aplicaciones empresariales est´n estructuradas en diferentes capas, donde cada una a de ellas se comporta como un componente software totalmente independiente y que puede interactuar con otro componente. Una de las separaciones en capas que se puede ver m´s a frecuentemente es la de modelo, vista y controlador. El modelo es el que define la l´gica de negocio de la aplicaci´n, es totalmente indepeno o diente de la vista y del controlador. En ´l residen los objetos de la aplicaci´n incluyendo e o sus datos y comportamiento.
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 3 Por otro lado la vista es la encargada de la representaci´n de los datos en una interfaz o de usuario para interactuar con este. Esta capa tambi´n es independiente de las dem´s e a aunque necesita conocer al modelo que es donde tiene que recoger los datos a representar. Por su parte el controlador es el encargado de conectar el modelo y la vista. Este recoge los eventos producidos por el usuario sobre la capa vista e invoca a las acciones pertinentes de la capa del modelo. JDBC Java Database Connectivity. Es un API que permite la ejecuci´n de operaciones o sobre bases de datos desde Java. Con este API se define una interfaz que permite interactuar con gran variedad de bases de datos relacionales. Este API forma parte de la edici´n o est´ndar de java (J2SE) y tambi´n de la edici´n empresarial (J2EE). a e o Los drivers JDBC son implementaciones particulares del API de JDBC para una base de datos relacional particular, y facilitan mucho el acceso a las bases de datos. En el caso de este proyecto se utiliza un driver JDBC para MySQL. JUnit Es un ‘framework‘, conjunto de clases, que permite probar el funcionamiento de clases Java de manera controlada. Probando el funcionamiento de cada uno de los m´todos e de la clase para ver que se comporta como se espera. Es decir, en funci´n de ciertos valores o de entrada se eval´an y luego se comprueba que la respuesta es la esperada, si la clase u cumple con la especificaci´n, entonces JUnit devolver´ que el m´todo de la clase pas´ exio a e o tosamente la prueba, en caso de que el valor esperado sea diferente al que devolvi´ el o m´todo durante la ejecuci´n, JUnit devolver´ un fallo en el m´todo correspondiente. e o a e A trav´s de JUnit tambi´n se puede controlar que despu´s de hacer cambios en la e e e implementaci´n de una clase, se sigan cumpliendo las especificaciones. o El propio framework incluye formas de ver los resultados que pueden ser en modo texto o gr´fico. Y en la actualidad las herramientas de desarrollo como NetBeans y Eclipse a cuentan con plugins que permiten que la generaci´n de las plantillas necesarias para la o creaci´n de las pruebas de una clase Java se realice de manera autom´tica, facilitando al o a
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 4 programador enfocarse en la prueba y el resultado esperado, y dejando a la herramienta la creaci´n de las clases que permiten coordinar las pruebas. o JSP Java Server Pages, es una tecnolog´ Java que permite generar contenido din´mico ıa a para web, en forma de documentos HTML, XML o de otro tipo. Estos documentos deben de estar contenidos en un servidor web que soporte esta tecnolog´ y se compilan a clases ıa, java la primera vez que se accede a cada p´gina. a Las JSP’s permiten la utilizaci´n de c´digo Java mediante scripts. Adem´s, es posible o o a utilizar algunas acciones JSP predefinidas mediante etiquetas. Estas etiquetas pueden ser enriquecidas mediante la utilizaci´n de librer´ de etiquetas externas, como las que o ıas proporciona el framework struts, e incluso se pueden constru´ etiquetas personalizadas. ır JSTL JavaServer Pages Standard Tag Library, es un componente de Java EE. Extiende las JavaServer Pages (JSP) proporcionando librer´ de etiquetas con utilidades ampliaıas mente utilizadas en el desarrollo de p´ginas web din´micas. a a Las diferentes librer´ de JSTL permiten realizar tareas comunes en el desarrollo de ıas la mayor´ de las aplicaciones web din´micas, estas tareas son: iteradores para recorrer ıa a colecciones de elementos y poder mostrarlos, etiquetas condicionales por si hay que escoger entre varias opciones, y unas de las m´s utilizadas, las etiquetas de internacionalizaci´n, a o que facilitan en gran medida el proceso de cambiar f´cilmente el idioma de la aplicaci´n a o as´ como el formateo de datos para los diferentes pa´ ı ıses. HTML HyperText Markup Language, es el lenguaje de marcado m´s utilizado para a la construcci´n de p´ginas web. Es usado para describir la estructura y el contenido en o a forma de texto, as´ como para complementar el texto con objetos tales como im´genes, ı a tablas, etc. Este es el lenguaje de marcado que son capaces de interpretar los navegadores web. La sintaxis de este lenguaje de marcado consiste en escribir ‘etiquetas‘ que estar´n a rodeadas por corchetes angulares, ‘<etiqueta>‘. HTML tambi´n puede describir, hasta e
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 5 un cierto punto, la apariencia de un documento, y puede incluir un script que puede afectar el comportamiento de navegadores web y otros procesadores de HTML. Aunque normalmente, y lo m´s correcto es separar la apariencia y el comportamiento en diferentes a ficheros. XML EXtensible Markup Language, es un metalenguaje extensible de etiquetas desa- rrollado por el World Wide Web Consortium (W3C). Es una simplificaci´n y adaptaci´n o o del SGML y permite definir la gram´tica de lenguajes espec´ a ıficos. Por lo tanto XML no es realmente un lenguaje en particular, sino una manera de definir lenguajes para diferentes necesidades. Algunos de estos lenguajes que usan XML para su definici´n son XHTML, o SVG, MathML. XML no ha nacido s´lo para su aplicaci´n en Internet, sino que se propone como un o o est´ndar para el intercambio de informaci´n estructurada entre diferentes plataformas. Se a o puede usar en bases de datos, editores de texto, hojas de c´lculo y casi cualquier cosa a imaginable. XML es una tecnolog´ sencilla que tiene a su alrededor otras que la complementan ıa y la hacen mucho m´s grande y con unas posibilidades mucho mayores. Tiene un papel a muy importante en la actualidad ya que permite la compatibilidad entre sistemas para compartir la informaci´n de una manera segura, fiable y f´cil. o a CSS Cascade Style Sheet, como su nombre indica son hojas de estilo, se utilizan para definir la apariencia de una p´gina web. En el documento HTML simplemente hay que a indicar en cada etiqueta un identificador que servir´ para luego establecer su apariencia a a partir del CSS. CSS es una herramienta muy potente, dado que permite hacer cambios radicales en la apariencia de una p´gina sin tener que modificar en absoluto el c´digo fuente. Permite a o realizar casi cualquier cosa imaginable, desde cambiar tama˜os, fuentes o colores, hasta la n posici´n y el comportamientdo de los distintos elementos de una p´gina. o a
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 6 Apache Struts Apache Struts es un framework gratuito de c´digo abierto para crear o aplicaciones web en Java de forma sencilla y r´pida. a Las aplicaciones web difieren de las p´ginas web convencionales en que las aplicaciones a web pueden crear una respuesta din´mica. Muchos sitios web ofrecen s´lo las p´ginas a o a est´ticas. Una aplicaci´n web puede interactuar con bases de datos o motores de la l´gica a o o de negocio para personalizar una respuesta. En las aplicaciones basadas en JavaServer Pages, a veces se mezclan el c´digo de acceso o a base de datos con c´digo de dise˜o de la misma, y el c´digo de control de flujo. En o n o la pr´ctica, nos encontramos con que a menos que estas preocupaciones est´n separadas, a a aplicaciones grandes son muy dif´ ıciles de mantener. Una forma de separar las distintas partes de una aplicaci´n de software es utilizar una o arquitectura Modelo-Vista-Controlador (MVC). El modelo representa la empresa o de base de datos de c´digo, la vista representa el c´digo de dise˜o de la p´gina, y el Contralor o o n a representa el c´digo de la navegaci´n. La plataforma Struts est´ dise˜ada para ayudar a o o a n los desarrolladores a crear aplicaciones web que utilizan una arquitectura MVC. MySQL 5.0 Es un sistema de gesti´n de base de datos relacional, multihilo y multio usuario con m´s de seis millones de instalaciones. Este sistema de gesti´n es uno de los m´s a o a utilizados, porque, a parte de tener una licencia GPL, libre y gratuita, es f´cil de utilizar a en proyectos peque˜os y actualmente es compatible con las tecnolog´ m´s importantes n ıas a del mercado, las cuales proporcionan APIs para conectarse y realizar consultas contra la base de datos. MySQL AB, desde enero de 2008 una subsidiaria de Sun Microsystems y esta a su vez de Oracle Corporation desde abril de 2009, desarrolla MySQL como software libre en un esquema de licenciamiento dual. Esto ultimo consiste en que por un lado se ofrece bajo la GNU GPL para cualquier ´ uso compatible con esta licencia, pero para aquellas empresas que quieran incorporarlo en
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 7 productos privativos deben comprar a la empresa una licencia espec´ ıfica que les permita este uso. Est´ desarrollado en su mayor parte en ANSI C. a Al contrario de proyectos como Apache, donde el software es desarrollado por una comunidad p´blica y el copyright del c´digo est´ en poder del autor individual, MySQL es u o a propietario y est´ patrocinado por una empresa privada, que posee el copyright de la maa yor parte del c´digo. Esto es lo que posibilita el esquema de licenciamiento anteriormente o mencionado. Adem´s de la venta de licencias privativas, la compa˜´ ofrece soporte y sera nıa vicios. Para sus operaciones contratan trabajadores alrededor del mundo que colaboran v´ Internet. ıa Apache Tomcat Apache Tomcat es una servidor web de c´digo abierto, que sirve como o contenedor de p´ginas web para las tecnolog´ Java Servlet y JavaServer Pages. a ıas Apache Tomcat est´ desarrollado en un entorno abierto y participativo por la compa˜´ a nıa Apache y publicado bajo la licencia Apache Software. Est´ en continuo desarrollo y mantea nimiento, y aunque hay diferentes productos no gratuitos que ofrecen m´s funcionalidades, a para una aplicaci´n sencilla, es suficiente para ejecutarla. o IDE Eclipse Es un entorno de desarrollo integrado de c´digo abierto multiplataforma o para desarrollar lo que ´l llama ‘Aplicaciones de Cliente Enriquecido‘, opuesto a las aplie caciones ‘Cliente-liviano‘ basadas en navegadores. Esta plataforma, t´ ıpicamente ha sido usada para desarrollar entornos de desarrollo integrados (del ingl´s IDE), como el IDE de e Java llamado Java Development Toolkit (JDT) y el compilador (ECJ) que se entrega como parte de Eclipse (y que son usados tambi´n para desarrollar el mismo Eclipse). Sin embare go, tambi´n se puede usar para otros tipos de aplicaciones cliente, y para otros lenguajes e de programaci´n. Adem´s es un entorno que posibilita la utilizaci´n de plugins por lo que o a o se pueden a˜adir los plugins que se necesiten y ampliar de esa forma las funcionalidades n que se estimen oportunas.
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 8 Eclipse es tambi´n una comunidad de usuarios, extendiendo constantemente las ´reas e a de aplicaci´n cubiertas. Un ejemplo es el recientemente creado Eclipse Modeling Project, o cubriendo casi todas las ´reas de la Ingenier´ dirigida por el modelo. a ıa Eclipse fue desarrollado originalmente por IBM como el sucesor de su familia de herramientas para VisualAge. Eclipse sigue siendo desarrollado por la fundaci´n Eclipse, o una organizaci´n independiente sin ´nimo de lucro que fomenta una comunidad de c´digo o a o abierto y un conjunto de productos complementarios, capacidades y servicios. PhpMyAdmin Es una herramienta de software libre escrito en PHP hecho con la in- tenci´n de manejar la administraci´n de MySQL en la World Wide Web. PhpMyAdmin o o es compatible con una amplia gama de operaciones con MySQL. Las operaciones m´s a frecuentes son el apoyo de la interfaz de usuario (gesti´n de bases de datos, tablas, camo pos, relaciones, ´ ındices, usuarios, permisos, etc) mientras que el usuario todav´ tiene la ıa capacidad de ejecutar directamente cualquier sentencia SQL. Configurar PhpMyAdmin es muy sencillo y facilita mucho la tarea de administrar las distintas bases de datos que necesita una aplicaci´n. As´ como la de realizar las diferentes o ı consultas que se puedan querer hacer. Mozilla Firefox Es un navegador de Internet libre y de c´digo abierto descendiente de o Mozilla Application Suite, desarrollado por la Corporaci´n Mozilla, la Fundaci´n Mozilla o o y un gran n´mero de voluntarios externos. u Firefox es un navegador multiplataforma y est´ disponible en varias versiones de Mia crosoft Windows, Mac OS X, GNU/Linux y algunos sistemas Unix. Su c´digo fuente es o software libre, publicado bajo una triple licencia GPL/LGPL/MPL. Actualmente cuenta con un alto porcentaje del mercado de navegadores web, haciendo as´ firme competencia al navegador Internet Explorer de Microsoft. Y cada a˜o este naı n vegador gana nuevos adeptos, gracias, entre otras cosas, al licenciamiento como software
    • 1.2. Herramientas y tecnolog´ para la Implementaci´n ıas o 9 libre y a que cuenta con un gran n´mero de personas que consiguen sacar parches para u errores puntuales en un tiempo r´cord gracias al eficaz sistema de reporte de errores. e Para visualizar p´ginas web, Firefox usa el motor de renderizado Gecko, que implementa a la mayor´ de los est´ndares web actuales adem´s de otras funciones, algunas de las cuales ıa a a est´n destinadas a anticipar probables adiciones a los est´ndares web. a a Incluye navegaci´n por pesta˜as, corrector ortogr´fico, b´squeda progresiva, marcadores o n a u din´micos, un administrador de descargas y un sistema de b´squeda integrado que utiliza a u el motor de b´squeda que desee el usuario. Adem´s se pueden a˜adir funciones a trav´s u a n e de complementos desarrolladas por terceros, muy util a la hora de comprobar aplicaciones ´ web o de realizar el dise˜o de la interfaz de usuario de estas. n Apache Maven 2 Maven 2 es una herramienta para la gesti´n de proyectos software que o proporciona soluciones a tareas comunes a todos los proyectos desde la compilaci´n inicial o hasta la distribuci´n e instalaci´n en los sistemas finales. Maven genera una estructura de o o directorios y ficheros que sirve de estructura base. Esta estructura de directorios es est´ndar a en todos los proyectos lo que permite a los desarrolladores moverse entre proyectos con mayor comodidad y familiaridad, algo muy importante a la hora de que otro desarrollador mantenga una aplicaci´n, ya que siempre sabr´ donde puede encontrar las cosas. o a Maven utiliza un fichero XML conocido como Project Object Model (POM) para describir el proyecto de software a construir, sus dependencias de otros m´dulos y componentes o externo, y el orden de construcci´n de los elementos. Esta es una caracter´ o ıstica importante de Maven ya que el desarrollador no se tiene que preocupar de tener las dependencias de su proyecto, simplemente se describen en el fichero POM las que necesitar´ y Maven ya a se encarga de tenerlas preparadas, siempre y cuando disponga de conexi´n a Internet, ya o que le har´ falta en caso de que tenga que descargar las dependencias que necesita. a
    • 1.3. Herramientas y tecnolog´ para la Documentaci´n ıas o 10 1.3. Herramientas y tecnolog´ para la Documentaci´n ıas o A L TEX Es un lenguaje de marcado para documentos, y un sistema de preparaci´n de o documentos, formado por un gran conjunto de macros de TEX, escritas inicialmente por Leslie Lamport (LamportTeX) en 1984, con la intenci´n de facilitar el uso del lenguaje de o composici´n tipogr´fica creado por Donald Knuth. Es muy utilizado para la composici´n o a o de art´ ıculos acad´micos, tesis y libros t´cnicos, dado que la calidad tipogr´fica de los e e a A documentos realizados con L TEX es comparable a la de una editorial cient´ ıfica de primera A l´ ınea. L TEX es software libre bajo licencia libre. Kile A Es una herramienta para trabajar con L TEX en GNU/Linux. Facilita entre otras cosas las labores de compilaci´n L TEX y de generaci´n de documentos. Adem´s proporo A o a ciona caracter´ ısticas algunas t´ ıpicas de los entornos de edici´n de texto ‘wysiwyg‘ como o Microsoft Word o OpenOffice Writer. Los comandos b´sicos para la edici´n de un texa o A to L TEX no hay que sab´rselos, ya que Kile proporciona un entorno que facilita mucho e el aspecto de escribir los comandos, proporcionando en forma de botones aquellos m´s a utilidados. A continuaci´n se se˜alan algunas cuestiones de configuraci´n que resulta util o n o ´ conocer. Configurar bien la codificaci´n de la p´gina, ya que, salvo que se le indique lo contrario, o a Kile utiliza la codificaci´n que el sistema GNU/Linux tiene activada por defecto. En las o configuraciones modernas la codificaci´n frecuentemente es utf-8 (unicode). Sin embargo lo o A m´s habitual en los documentos L TEX que utilizamos es usar latin1, que corresponde con a la codificaci´n iso 8859-1 o iso 8859-15 si los textos en espa˜ol van a utilizar alg´n s´ o n u ımbolo especial. Si al abrir un archivo aparecen caracteres raros esto indica una configuraci´n de o codificaci´n de Kile no es la correcta y habr´ que modificarla. o a Planner Aplicaci´n software libre para realizar planificani´n de proyectos, utililzada o o para la planificaci´n del proyecto actual y la evaluaci´n de costes. Entre sus funcionalidades o o
    • 1.3. Herramientas y tecnolog´ para la Documentaci´n ıas o 11 se puede observar la del c´lculo del coste asociado a cada una de las tareas, realizaci´n de a o diagramas de Gantt para seguir la realizaci´n del proyecto. o El unico inconveniente de esta aplicaci´n es que no exporta a ning´n formato de imagen ´ o u los diagramas finales. GIMP Es un editor de im´genes software libre que permite crear y modificar im´genes de a a distintos formatos y exportarlas finalmente a pr´cticamente cualquier formato de imagen. a Este editor tiene unas prestaciones parecidas al programa Photoshop de Adobe pero con las ventajas de que no hay que pagar una licencia por ´l, es c´modo de usar y, auque tiene e o una curva de aprendizaje larga, es muy r´pido de utilizar una vez que se sabe manejar. a
    • Cap´ ıtulo 2 Estado actual de las tecnolog´ ıas utilizadas Antes de desarrollar cualquier proyecto software lo primero que hay que hacer es identificar todas las tecnolog´ que se utilizar´n en el mismo. Para ello un desarrollador se ıas a sirve de su experiencia con las distintas herramientas y de los requisitos que tendr´ que a cumplir la aplicaci´n que va a desarrolar, ya que algunas tecnolog´ no permitir´n que o ıas a estos se cumplan. En un primer lugar para este proyecto se descartar´n autom´ticamente todas aquellas a a tecnolog´ que impidan licenciar el sistema final como software libre, siendo b´sicamente ıas a todas aquellas que est´n licenciadas bajo una licencia privativa. En ciertas situaciones e ser´ complicado encontrar aplicaciones, y tecnolog´ libres equivalentes a las tecnolog´ a ıas ıas privativas m´s comunes, adem´s de ser una dificultad el encontrar alg´n software, tambi´n a a u e influir´ en el tiempo de desarrollo del proyecto, ya que habr´ que aprender a manejar las a a tecnolog´ elegidas. ıas Cuando se quiere desarrollar una aplicaci´n web lo primero que hay que identificar es o la plataforma a utilizar, en este caso J2EE, ya se sab´ de antemano porque era uno de ıa los requisitos del proyecto, pero aparte de J2EE hay otras alternativas como pueden ser la 13
    • 14 plataforma .NET o PHP, cualquiera de ellas se podr´ utilizar. En el caso de J2EE la curva ıa de aprendizaje es muy larga, entre otras cosas porque se necesita saber utilizar un unico ´ lenguaje de programaci´n, pero a parte de eso se necesitan aprender como funcionan las o diferentes tecnolog´ que se utilizar´n conjuntamente a la hora de desarrollar el proyecto. ıas a En este caso J2EE y PHP tienen multitud de comunidades de usuarios ya sea de los propios proyectos, Apache, MySQL, como grupos independientes de desarrolladores, mientras que en proyectos .NET las comunidades de desarrolladores est´n controladas y gestionadas a por Microsoft. Aunque la tecnolog´ a utilizar no estuviera previamente determinada, .NET no se podr´ ıa ıa utilizar debido a que su entorno de desarrollo integrado es propietario y de un coste muy elevado que har´ inviable el proyecto, frente a los entornos de desarrollo que existen en el ıa mercado para trabajar con J2EE entre los que destaca Eclipse, considerado por muchos el mejor entorno de desarrollo integrado libre del mercado. Adem´s hay otros aspectos de a J2EE que corren a su favor, como la portabilidad entre diferentes plataformas, gracias en gran medida a estar todo realizado en Java. Esto proporciona que el proyecto final sea totalmente independiente de la plataforma, cosa que no sucede con .NET que hasta el momento s´lo se puede montar sobre plataformas de Microsoft. Del mismo modo .NET o s´lo cuenta con servidores comerciales de pago mientras que J2EE funciona tanto sobre o servidores de pago como libres. Por otra parte dada la naturaleza del proyecto y a que se licenciar´ como software libre a para que otros desarrolladores puedan agregar nuevas mejoras, este debe ser f´cilmente a escalable, por eso tambi´n en este caso de adapta perfectamente J2EE que permite gran ese calabilidad por si en el futuro se desea integrar esta aplicaci´n con otras para proporcionar o m´s funcionalidades. a J2EE nos es la opci´n m´s r´pida del mercado, ya que en este aspecto otras tecnolog´ o a a ıas como PHP no tienen competidor, pero es lo suficientemente r´pido para dar soporte a las a necesidades de la aplicaci´n final. o
    • 15 Se necesita tambi´n un gestor de bases de datos para el proyecto y para ello habr´ que e a tener en cuenta de igual forma que sea una tecnolog´ libre, por lo que quedan descartaıa dos gestores de bases de datos como Oracle. Entre la oferta disponible destacan MySQL y PostgreSQL, y puestos a tener que elegir, como ambas ofrecen m´s o menos las misa mas prestaciones, se utilizar´ MySQL dada la familiaridad que se tiene, a que tiene una a comunidad de usuarios bien organizada y al bajo coste debido a su licencia libre.
    • Cap´ ıtulo 3 Estudio de viabilidad Obviamente antes de realizar el proyecto que aqu´ se est´ detallando, se estudi´ si era ı a o viable realizarlo y terminarlo con ´xito en el tiempo previsto, puesto que, al ser un proyecto e acad´mico para dar fin a la formaci´n que se ha estado recibiendo, la fecha l´ e o ımite ser´ la ıa que marcaran las convocatorias para la entrega del proyecto. Si el proyecto no fuese viable no se podr´ realizar porque no se tendr´ la garant´ de terminarlo. ıa ıa ıa A parte del tiempo del que se dispone para la realizaci´n de esta aplicaci´n, tambi´n es o o e un factor decisivo para estudiar la viabilidad del mismo, el coste, que deber´ ser el m´ a ınimo posible. Este proyecto no solo valdr´ para terminar los estudios, sin´ que se har´ de tal forma a o a que sea facilmente ampliable para que en el futuro se pueda adaptar para una aplicaci´n o empresarial real con muy poco esfuerzo y haciendo los m´ ınimos cambios posibles. Para posibilitar la realizaci´n de futuros cambios, en la realizaci´n del dise˜o de la aplicaci´n ya o o n o se han tenido en cuenta posibles puntos de amplicaci´n. De esta forma se podr´ adaptar o ıa la aplicaci´n para venderla, y con muy pocos cambios sacarle mucha rentabilidad a la o aplicaci´n web. o Por otro lado como la realizaci´n del proyecto s´lo se har´ por parte de una persona, o o a este no se har´ demasiado extenso para que sea viable realizarlo en 4 o 6 meses. a 17
    • 18 Para que cualquier proyecto sea rentable realizarlo hay que tener en cuenta el coste en cuanto a tiempo de desarrollo y tambi´n el coste derivado de la utilizaci´n de las distintas e o tecnolog´ Por esa raz´n para que la realizaci´n del proyecto saliese rentable, se decide ıas. o o utilizar solamente software libre y gratuito, gracias a esto tambi´n cabe la posibilidad de e licenciar la aplicaci´n final como software libre. o A continuaci´n se detallan algunas de las tecnolog´ y herramientas software consideo ıas radas y finalmente utilizadas, as´ como su coste asociado. ı Herramienta Descripci´n o MySQL Gestor de base de datos relacional utilizado para almacenar los datos de la aplicaci´n o Entorno de programaci´n integrado o utilizado para realizar la programaci´n de la aplicaci´n o o Servidor de Aplicaciones Web utilizado contener la aplicaci´n o Editor de diagramas utilizados utilizados para realizar los diagramas del modelo Entidad-Relaci´n de la o base de datos Editor de diagramas UML utilizados para realizar los diagramas UML del modelo de la aplicaci´n o Aplicaci´n utilizada para gestionar o y monitorizar las bases de datos utilizadas Editor de textos para A L TEXutilizado para realizar toda la documentaci´n necesaria para o la aplicaci´n o IDE Eclipse Apache Tomcat DIA Argo UML PhpMyAdmin Kile Cantidad Precio (e) 1 0.00 1 0.00 1 0.00 1 0.00 1 0.00 1 0.00 1 0.00 Cuadro 3.1: Tabla de costes para estudio de viabilidad Resumiendo, gracias a las licencias libres de todas las herramientas y tecnolog´ utiliıas zadas, el coste total de todas es de 0.00e, por lo que el coste final ser´ igual al coste del a tiempo empleado en el desarrollo de la aplicaci´n. Esto cambiar´ si se utilizasen herrao ıa
    • 19 mientas y tecnolog´ de pago, porque s´lo por el coste de las licencias, el proyecto que se ıas o desea realizar ser´ totalmente inviable para realizar como proyecto fin de carrera. ıa
    • Cap´ ıtulo 4 Introducci´n al desarrollo o realizado 4.1. El Proceso Unificado Para realizar este proyecto se utiliza una metodolog´ basada en iteraciones, donde en ıa cada una de ellas se consigue implementar un conjunto de funcionalidades de la aplicaci´n, o casos de uso, y as´ al terminar la utima iteraci´n se tiene un sofware que implementa todos ı ´ o los casos de uso. En cada una de las iteraciones se realizar´ an´lisis, dise˜o, implementaci´n y pruebas. a a n o Para realizar estas iteraci´nes se utiliza la metodolog´ que define el Proceso Unificado, o ıa (UP, Unified Process). Este proceso de desarrollo, acompa˜ado del leguaje de modelado n UML (Unified Modelling Languaje) son, conjuntamente, la metodolog´ que m´s se utiliza ıa a actualmente a la hora de desarrollar un nuevo proyecto software. El Proceso Unificado de desarrollo software es un marco de desarrollo software iterativo e incremental, el UP se puede extender para ser adaptado a organizaciones o proyectos expec´ ıficos, de hecho, el refinamiento m´s conocido del Proceso Unificado es el Proceso a 21
    • 4.1. El Proceso Unificado 22 Unificado de Rational que es un marca registrada de IBM, pero hay otros muchos refinamientos: Agile UP, Open UP, etc. El UP est´ compuesto por cuatro fases denominadas Concepci´n, Elaboraci´n, Consa o o trucci´n y Transici´n, donde cada una de estas fases se divide en iteraciones. Cada una o o de las iteraciones ofrece como resultado un incremento del producto que a˜ade o mejora n funcionalidades del sistema. Cada iteraci´n se divide en disciplinas c´mo las que se defin´ en el ciclo de vida o o ıan cl´sico: An´lisis de requisitos, Dise˜o, Implementaci´n, Pruebas, etc. Pero, aunque todas a a n o las iteraciones incluyen trabajo en casi todas las disciplinas, cada una de ellas se centra m´s en una iteraci´n u otra. Este ´nfasis en cada iteraci´n se puede observar en el gr´fico a o e o a de la figura 4.1. Figura 4.1: Gr´fico del Proceso Unificado a El Proceso Unificado se caracteriza, entre otras cosas, por estar dirgido por los casos de uso, estos se utilizan para capturar los requisitos funcionales y para definir los contenidos de cada iteraci´n. Estos contenidos son los recogidos en un cada uno de los conjuntos o
    • 4.1. El Proceso Unificado 23 de casos de uso o escenarios, de forma que cada iteraci´n pase a trav´s de todas las o e disciplinas: dise˜o, implementaci´n, etc. Adem´s, siguiendo este proceso de desarrollo, hay n o a que centrarse en los riesgos, es decir, se deben identificar los riesgos cr´ ıticos que pueden afectar al desarrollo del proyecto lo antes posible. Identificando los riesgos en una etapa temprana luego el desarrollo se debe centrar en resolver estos puntos cr´ ıticos en primer lugar. A continuaci´n se detalla lo que tiene lugar en las distintas fases del Proceso Unificado: o Fase de Concepci´n o Esta fase es la m´s peque˜a del proyecto, en ella se deben establer el ´mbito del a n a proyecto y una justificaci´n de por qu´ se realiza. o e Adem´s es en este momento cu´ndo se esbozan los casos de uso y los requisitos a a principales por los cuales se dirigir´n las cuestiones de dise˜o del proyecto. Por otro a n lado se deben comenzar a buscar las arquitecturas generales que mejor se adapten al proyecto que se quiere realizar e identificar los riesgos cr´ ıticos para el mismo. A continuaci´n se debe preparar un plan para el proyecto y una estimaci´n de los costes o o que este conllevar´. a Fase de Elaboraci´n o Es la fase en la cual se capturan la mayor´ de los requisitos del sistema, identificando ıa tambi´n los riesgos y estableciendo la arquitectura general del sistema. e Adem´s se debe implementar una Base de Arquitectura Ejecutable para demostrar a que el sistema final soportar´ los aspectos claves de funcionalidad establecidos y a comprobar que tiene un rendimiento, escalabilidad y coste adecuados. Fase de Construcci´n o Es la m´s larga del proyecto, donde se construye el sistema en base a lo especificado a en la fase de elaboraci´n. Esta fase se divide en una serie de iteraciones, y en cada o
    • 4.2. El Proceso Unificado en este Proyecto 24 una de ellas se implementa un conjunto de las funcionalidades, terminando cada una con una versi´n completa de la aplicaci´n final. o o Fase de Transici´n o Esta es la fase en la que se despliega la aplicaci´n para el usuario final, y recogiendo o las impersiones de estos para incorporar refinamientos al sistema en sucesivas iteraciones, esta fase tambi´n incluye el entrenamiento en la utilizaci´n del sistema por e o parte de los usuarios. 4.2. El Proceso Unificado en este Proyecto A continuaci´n se ver´ c´mo se aplic´ el Proceso Unificado en el desarrollo de este o a o o proyecto, para ello se ir´n indicando las diferentes fases por las que se fue pasando y las a iteraciones que se realizaron en cada una de ellas con una descripci´n de lo que se hizo. o Fase de Concepci´n o 1. Iteraci´n 1 o En esta iteraci´n se hizo un an´lisis de las funcionalidades que deber´ cono a ıa templar la aplicaci´n, estableciendo textualmente los requisitos principales del o sistema. A partir de este an´lisis de requisitos se realiz´ el dise˜o Entidad Relaci´n de a o n o la base de datos que necesitar´ la aplicaci´n, para luego realizar el modelo relaa o cional. A continuaci´n se implementa la base de datos en base a lo especificado o en el modelo relacional. Adem´s en este momento se vi´ que probablemente ser´ un riesgo a solventar a o ıa que el driver JDBC, que posteriormente se utilizar´ para conectarse a la base a de datos, funcionase correctamente. Se detect´ en este momento un mal funcioo namiento de la conexi´n con la base de datos y se resolvi´ despu´s de consultar o o e la documentaci´n espec´ o ıfica del manejador JDBC.
    • 4.2. El Proceso Unificado en este Proyecto 25 Fase de Elaboraci´n o 1. Iteraci´n 1 o En esta iteraci´n se realiza un an´lisis de requisitos m´s exhaustivo, realizando o a a el modelo de casos de uso. A partir de este an´lisis de requisitos se refina el a dise˜o de la base de datos y se implementan los cambios realizados. n Se dise˜a en este momento como ser´ la capa modelo, los DAO y las Fachadas n a que se necesitar´n. A partir de este dise˜o se implementa la capa de acceso a a n base de datos (DAO) y alguna de las fachadas, tambi´n se hacen las pruebas e de unidad correspondientes a estas implementaciones. Adem´s se hacen pruebas para ver como funciona la tecnolog´ struts que se a ıa utilizar´ para implementar la capa controladora de la aplicaci´n web. a o Fase de Construcci´n o 1. Iteraci´n 1 o En esta iteraci´n se refinan peque˜os detalles de los requisitos y se dise˜a la o n n capa controladora y la vista. Es ahora cuando se implementa un subconjunto completo de casos de uso, en este caso el referido a la gesti´n de usuarios. Se implementa desde las acciones o del modelo, que implementan realmente los casos de uso, hasta la capa vista. Entre estos casos de uso se encuentran los de autentificar al usuario en la aplicaci´n, darlo de alta, etc, para lo que tambi´n hay que implementar el mecanismo o e para mantener las sesiones. Para terminar con esta iteraci´n y conseguir una versi´n funcional del sistema o o se prueba que se realicen correctamente los requisitos especificados en los casos de uso. Iteraci´n 2 o
    • 4.2. El Proceso Unificado en este Proyecto 26 En este momento se refina el dise˜o de las fachadas que se van a implementar de n forma que se ajuste exactamente a lo que se desea. Adem´s se dise˜a la estructura a n general del sistema de ofertas con el que se iteractuar´ a la hora de realizar las a facturas. En este momento se implementan otros dos subconjuntos completos de casos de uso, en este caso los referidos a la gesti´n de reservas y habitaciones. Se implementa o desde las acciones del modelo que implementan realmente los casos de uso hasta la capa vista. Entre estos casos de uso se encuentran los de realizar una nueva reserva, consultar las reservas y modificarlas, para ello es necesario implementar una forma de gestionar la realizaci´n de las reservas. o Para terminar con esta iteraci´n y conseguir una versi´n funcional del sistema se o o prueba que se realicen correctamente los requisitos especificados en los casos de uso. Iteraci´n 3 o En este momento se refina el dise˜o del sistema de las ofertas para que se ajuste n exactamente a los requisitos requeridos por el mismo. En este momento se implementan otros dos subconjuntos completos de casos de uso, en este caso los referidos a la gesti´n de facturas y ofertas. Se implementa desde las o acciones del modelo que implementan realmente los casos de uso hasta la capa vista. Entre estos casos de uso se encuentran los de ver el borrador de una factura en el que entra en juego el sistema de ofertas desarrollado, pagar una factura o cancelarla, etc. Para terminar con esta iteraci´n y conseguir una versi´n funcional del sistema se o o prueba que se realicen correctamente los requisitos especificados en los casos de uso, prestando especial atenci´n al sistema de ofertas, ya que la unica forma de probarlo o ´ es en este momento, debido a la dificultad de realizar pruebas de unidad de cada uno de los m´todos que forman sus clases. e Fase de Transici´n o
    • 4.2. El Proceso Unificado en este Proyecto 27 Esta fase del Proceso Unificado no es necesaria realizarla para la realizaci´n del proo yecto debido a que en este caso s´lo valdr´ para evaluar los conocimientos adquiridos o a durantes los estudios realizados. Si este proyecto tuviese que ser adaptado para su comercializaci´n, ser´ en esta fase cuando se desplegar´ ante el usuario final para o ıa ıa que informase si todo est´ como se hab´ pedido y cuando se ense˜ar´ al usuario a a ıa n ıa utilizar la aplicaci´n. o
    • Cap´ ıtulo 5 Requisitos del Sistema 5.1. Introducci´n o Antes de comenzar cualquier proyecto de desarrollo de software, lo primero que hay que hacer es un an´lisis de requisitos del sistema, es decir, hay que conocer las caracter´ a ısticas que debe tener el sistema. Las caracter´ ısticas de una aplicaci´n las determinan el cliente que la solicita y el usuario o final que lo va a utilizar. En nuestro caso necesitamos una aplicaci´n que permita gestionar o las reservas de un hotel y dem´s partes del mismo, de una forma sencilla. El sistema a a desarrollar est´ orientado a las peque˜as y medianas empresas hoteleras, por lo que el a n coste del producto lo hay que reducir lo m´ximo posible. a En la actualidad la gran mayor´ de peque˜os hoteles o similares realizan sus tareas de ıa n una forma manual, o utilizando numerosos productos software. La gesti´n de las reservas o se suele hacer por tel´fono o en persona en el lugar donde se encuentre el establecimiento, e anotando las mismas en un libro de reservas ya sea, en formato papel o digital. Adem´s a necesitan un software especial para gestionar el proceso de facturaci´n del hotel, y no o tienen manera de gestionar de forma autom´tica y eficaz, todas las ofertas que puedan, o a quieran, tener a disposici´n del consumidor. o 29
    • 5.1. Introducci´n o 30 Las grandes firmas hoteleras y las cooperativas de varios hoteles no tienen estos problemas, ya que tienen financiamiento suficiente para contratar el desarrollo de aplicaciones que se ajusten a sus necesidades. Lo que se intenta hacer con este proyecto es ofrecer una soluci´n lo m´s gen´rica posible o a e para todas aquellas peque˜as empresas a las cuales un producto como este les facilitar´ n ıa much´ ısimo las cosas a la hora de gestionar sus modestos negocios, adem´s de proporcionar a la opci´n de gestionar un sitio web propio que est´ totalmente integrado, dando, entre o e otras cosas, la opci´n de hacer reservas y consultas on-line. o Una de las cosas m´s importantes es que este sistema se licenciar´ como software libre a a bajo una licencia GPL (General Public License), de modo que todo aquel que lo necesite pueda acceder a ´ste software de manera totalmente gratuita. e El desarrollo de este producto software est´ pensado para que, en caso necesario, sea a f´cilmente ampliable, configurable y ajustable, para adaptarse a las necesidades del usuario a final. Esta aplicaci´n contiene las funcionalidades b´sicas que un establecimiento hotelero o a pueda necesitar en su d´ a d´ pero est´ orientado a que en cualquier momento se puedan ıa ıa, a realizar cambios de forma sencilla y sin alterar su estructura general. El funcionamiento b´sico del sistema final tiene que dar soporte para dar de alta a a nuevos clientes, as´ como para la realizaci´n de reservas por parte de los clientes a trav´s ı o e de internet y en el establecimiento del hotel por parte del recepcionista, tambi´n dar´ la e a posibilidad de que el administrador gestione todas las partes m´s cr´ a ıticas del negocio, como son las habitaciones y sus precios, o la publicaci´n de nuevas ofertas para que est´n o e a disposici´n de los usuarios. o Cuando un nuevo usuario acceda a la aplicaci´n a trav´s de internet se le proporcionar´ la o e a oportunidad de darse de alta, o si ya lo est´, de acceder al sistema. Para ello se le pedir´n a a sus datos personales, los cuales ser´n utilizados posteriormente a la hora de realizar las a facturas a nombre del cliente. Si por el contrario el alta del nuevo cliente la realiza el recepcionista, se le pedir´n los mismos datos a excepci´n del nombre de usuario que desea a o
    • 5.1. Introducci´n o 31 y su contrase˜a, ya que esos datos se los tendr´ que pedir expl´ n a ıcitamente el cliente al recepcionista. Un cliente, una vez registrado y autentificado en el sistema tendr´, la posibilidad de a hacer una reserva para los d´ que desee. Para la realizaci´n de una reserva simplemente ıas o ser´ necesario que el cliente est´ registrado, pero esta reserva no ser´ una reserva real hasta a e a que el cliente la pague, para lo cual el administrador del hotel tendr´ que dar un plazo, a y si el cliente no paga la reserva dentro de ese plazo ´sta ser´ cancelada. De este modo e a se pueden evitar p´rdidas derivadas de intentos de sabotaje por parte de alg´n usuario e u malintencionado. Una vez realizada la misma, se le comunica al cliente el n´mero de reserva que deu ber´ buscar para pagar. A partir de ese momento el cliente puede consultar la reserva a realizada y modificarla si lo desea, o ver la factura y pagarla o cancelarla. La factura que ve el cliente se genera autom´ticament; para ello el sistema deber´ utilizar alg´n algoritmo a a u especial que permite aplicar las ofertas pertinentes. El sistema de ofertas es quiz´ una de las partes de la aplicaci´n m´s complicada de resola o a ver. Una oferta va a pertenecer a un tipo de ofertas; estos tipos los definir´ el administrador a (obviamente de cada tipo de oferta s´lo se podr´ aplicar una oferta). o a Hasta aqu´ la parte sencilla, este sistema tambi´n permitir´ acumular ofertas de forma ı e a que se puedan aplicar varios descuentos de ofertas distintas sobre el importe inicial, y dejar´ al administrador especificar mediante reglas altamente configurables, el conjunto a de clientes o aquellas situaciones espec´ ıficas en las cuales se podr´ aplicar una oferta; por a lo tanto, otro problema a solventar ser´ la definici´n de dicho lenguaje de reglas. a o Como acabamos de mencionar, de cada tipo de oferta solamente una se podr´ aplicar, a pero adem´s los tipos tendr´n incompatibilidades entre s´ relaciones mediante las cuales a a ı, se definir´ que ofertas no se pueden aplicar conjuntamente. La aplicaci´n debe resolver de a o forma r´pida y eficaz esta problem´tica, ya que a la hora de calcular la mejor oferta que a a
    • 5.2. Actores 32 se le puede ofrecer a un cliente sobre una factura, tendr´ que calcular cu´l es el conjunto a a de ofertas que a ´ste le proporcionar´ un mayor descuento. e a En las siguientes secciones se ver´n en detalle todas las situaciones que el sistema dea ber´ contemplar y resolver, y todos los usuarios que interactuar´n con la aplicaci´n. a a o Para la definici´n de las funcionalidades del sistema se emplear´ notaci´n UML (Unified o a o Modelling Language) especificando los usuarios del sistema y todos los que interact´an u con ´l (actores), y los comportamientos del mismo ante las peticiones de los actores (casos e de uso). Las funcionalidades b´sicas de este producto se definir´n en cojuntos de casos de uso, a a a trav´s de los cuales se detallar´ el funcionamiento de la aplicaci´n. e a o 5.2. Actores Como se acaba de mencionar, un actor es alguien o algo que intercambia informaci´n o con el sistema, bien sea un usuario u otro sistema. Varios usuarios se pueden representar como un s´lo actor para el sistema y viceversa, un mismo usuario puede ser representado o por varios actores. Se pueden distinguir varios tipos de actores, de los cuales los m´s importantes son: a Los actores primarios y los de soporte. Los actores primarios son aquellos que utilizan el sistema para alcanzar sus objetivos y a trav´s de los cuales se pueden identificar los e objetivos a desarrollar en el sistema. Los actores de soporte son los que proveen un servicio al sistema, estos actores sirven para identificar interfaces externos a nuestro sistema que hay que utilizar. En nuestro sistema podemos encontrar los siguientes actores primarios: Persona Es toda persona que entra en la aplicaci´n y no se autentifica o se registra. Este o usuario puede hacer consultas de precios, ofertas y dem´s, pero no podr´ realizar a a
    • 5.3. Casos de Uso 33 ningua reserva. Este tipo de usuario tiene la opci´n de autentificarse o de registrarse o en el sistema. Cliente Es aquel usuario que se ha autentificado, tiene la posibilidad de hacer las mismas operaciones que una Persona, pero adem´s tambi´n puede realizar reservas de a e habitaciones, hacer consultas sobre sus reservas y facturas, y pagar o cancelar las reservas que desee. Entre otras cosas este usuario tambi´n puede actualizar su perfil e o darse de baja en el sistema. Recepcionista Es el empleado del hotel que se encarga de la recepci´n del mismo, este o usuario es el encargado de recibir a los clientes en el establecimiento y tiene la posibilidad de dar de alta a un nuevo cliente y realizarle una reserva si es necesario. Administrador Es el empleado encargado de gestionar y mantener todo el sistema por lo que tiene unos privilegios que no posee ning´n otro usuario. u C´mo el Cliente va a poder hacer las mismas operaciones que la Persona, esto significa o que entre los dos constituyen una jerarqu´ de usuarios. ıa Pero adem´s la aplicaci´n necesita un indispensable actor de soporte: a o Entidad Financiera Es el sistema de pago contra el cual nuestro sistema tiene que realizar y verificar los pagos de las reservas. Este usuario permite que las reservas se puedan pagar on-line. 5.3. Casos de Uso Un caso de uso es una forma de definir el escenario completo de una operaci´n. Un caso o de uso especifica claramente lo que hace una operaci´n desde el punto de vista del actor o que la realiza. En ´l aparecer´n exclusivamente aquellos detalles que son relevantes para e a el actor.
    • 5.3. Casos de Uso 34 En primer lugar se expecificar´n los distintos casos de uso siguiendo las especificaciones a que proporciona el proceso de desarrollo unificado, que es el que se est´ siguiendo en la a elaboraci´n de este proyecto. Estas especificaciones indican que el detallado de un caso de o uso debe contener la siguiente informaci´n: actores, precondiciones, postcondiciones, flujo o b´sico y flujo alternativo. a Los actores son los usuarios implicados en el caso de uso en cuesti´n. Las precondiciones o especifican todas las condiciones del sistema que son obligatorias que se cumplan antes de que comience el caso de uso. Por otro lado, las postcondiciones son aquellas condiciones en las que, con toda seguridad, quedar´ el sistema una vez termine la ejecuci´n del caso a o de uso. Aunque lo m´s importante para detallar un caso de uso es indicar cu´l va a ser su flujo a a b´sico de eventos y cu´l su flujo alternativo. El flujo b´sico de eventos indica los eventos a a a que se han de realizar para que el caso de uso termine exitosamente. El flujo alternativo es aquel flujo de eventos que se seguir´ en caso de que alg´n fallo ocurra durante el flujo a u b´sico del mismo. a Una vez aclarados estos conceptos ya se puede comenzar a detallar cada uno de los casos de uso de este sistema, y para que se puedan entender mejor van a estar agrupados por conjuntos donde est´n contextualmente relacionados entre s´ a ı. 5.3.1. Casos de Uso de Gesti´n de Usuarios Web o Estos casos de uso son todos aquellos relacionados con la gestion de los Usuarios del sistema, registro, autentificaci´n, etc. Se puede ver el diagrama correspondiente en la figura o 5.1 de la p´gina 78. a 1. Autenticarse Actores Primarios: Cliente, Recepcionista, Administrador.
    • 5.3. Casos de Uso 35 Descripci´n: Permite a una persona entrar en el sistema. o Precondiciones: La persona a´n no est´ autenticada en el sistema. u a Postcondiciones: La persona pasa a estar autenticada en el sistema. Flujo b´sico: a 1 La persona quiere autenticarse en el sistema. 2 El sistema pide a la persona que introduzca su nombre de usuario y su contrase˜a. n 3 La persona introduce su nombre de usuario y su contrase˜a. n 4 La persona confirma que desea autenticarse. 5 El sistema autentica a la persona. Flujo alternativo: *.1 En cualquier momento la persona tiene la posibilidad de cancelar el proceso. 4.1 La persona no ha introducido el login, la contrase˜a o ambos. n 4.2 El sistema indica que tiene que indicar el nombre de usuario y contrase˜a. n 4.3 Se vuelve al evento 2 del flujo b´sico. a 5.1 El nombre de usuario o contrase˜a son incorrectos. n 5.2 El sistema se lo indica a la persona y le da la opci´n de registrarse. o 5.3 Se vuelve al paso 2. 2. Salir del sistema Actores Primarios: Cliente, Recepcionista, Administrador Descripci´n: Permite a un cliente dejar de estar autenticado en el sistema. o Precondiciones: El cliente est´ autenticado en el sistema. a
    • 5.3. Casos de Uso 36 Postcondiciones: El cliente deja de estar autenticado en el sistema. Flujo b´sico: a 1 La persona quiere salir del sistema. 2 El sistema pide al cliente que confirme que desea salir del sistema. 3 El cliente confirma que desea salir. 4 El sistema procesa la petici´n y el cliente deja de estar autenticado en la o aplicaci´n. o Flujo alternativo: *.1 En cualquier momento la persona tiene la posibilidad de cancelar el proceso. 3. Dar de Alta Usuario Actores Primarios: Persona Descripci´n: Permite a una nueva persona que entra en el portal Web del hotel darse de alta o como usuario del mismo. Precondiciones: La persona no est´ autenticada en el sistema. a Postcondiciones: La persona pasa a estar autenticada en el sistema y se registra como nuevo usuario de este. Flujo b´sico: a 1 La persona quiere darse de alta en el sistema. 2 El sistema pide a la persona que introduzca los siguientes datos de los cuales algunos son obligatorios: • Nombre (obligatorio)
    • 5.3. Casos de Uso 37 • Apellidos (obligatorio) • DNI o pasaporte (obligatorio) • Fecha de Nacimiento (obligatorio) • Direcci´n completa (obligatorio) o • Pa´ (obligatorio) ıs • Direcci´n de e-mail (obligatorio) o • Tel´fono1 (opcional) e • Tel´fono2 (opcional) e • Nombre de Usuario (obligatorio) • Contrase˜a (obligatorio) n • Confirmaci´n de contrase˜a (obligatorio) o n 3 La persona introduce los datos solicitados. 4 La persona confirma que desea darse de alta. 5 El sistema procesa la informaci´n del nuevo cliente. o 6 La persona pasa a estar dada de alta como cliente. 7 El sistema autentica al cliente en la aplicaci´n. o 8 El cliente est´ autenticado en el sistema. a Flujo alternativo: *.1 En cualquier momento la persona tiene la posibilidad de cancelar el proceso. 4.1.1 La persona no ha introducido todos los datos obligatorios o las contrase˜as no coinciden. n 4.1.2 El sistema indica que tiene que introducir los datos obligatorios y se vuelve al evento 2 del flujo b´sico. a 4.2.1 El nombre de usuario ya existe como nombre de usuario de otro cliente. 4.2.2 Se solicita que cambie el nombre de usuario y se vuelve al paso 2. 4.3.1 El dni indica que esa persona ya est´ dada de alta. a
    • 5.3. Casos de Uso 38 4.3.2 Se le pide a la persona que compruebe que ha escrito bie su dni y se vuelve al paso 2. 4. Modificar datos de Usuario Actores Primarios: Cliente, Recepcionista, Administrador Descripci´n: Permite a un cliente modificar los datos con los que se di´ de alta como usuario o o del sistema. Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: Los datos del cliente est´n actualizados. a Flujo b´sico: a 1 El cliente quiere midificar los datos con los que se di´ de alta en el sistema. o 2 El sistema muestra los datos actuales del cliente y pide al cliente que actualice los que desee de los siguientes: • Nombre (obligatorio) • Apellidos (obligatorio) • Fecha de Nacimiento (obligatorio) • Direcci´n completa (obligatorio) o • Pa´ (obligatorio) ıs • Direcci´n de e-mail (obligatorio) o • Tel´fono1 (opcional) e • Tel´fono2 (opcional) e • Contrase˜a (obligatorio) n • Confirmaci´n de contrase˜a (obligatorio) o n 3 El cliente modifica los datos que quiere.
    • 5.3. Casos de Uso 39 4 El cliente confirma que desea actualizar sus datos. 5 El sistema procesa la actualizaci´n de los datos del cliente. o 6 Los datos del cliente pasan a estar actualizados. Flujo alternativo: *.1 En cualquier momento la persona tiene la posibilidad de cancelar el proceso. 4.1 La persona no ha introducido todos los datos obligatorios o las contrase˜as n no coinciden. 4.2 El sistema indica que tiene que introducir los datos obligatorios y se vuelve al evento 2 del flujo b´sico. a 5. Consultar datos de Usuario Actores Primarios: Cliente, Recepcionista, Administrador Descripci´n: Permite a un cliente consultar los datos con los que se di´ de alta en el sistema. o o Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El cliente quiere consultar los datos con los que se di´ de alta en el sistema. o 2 El sistema muestra al cliente sus datos personales. 6. Dar de baja Usuario Actores Primarios: Cliente Descripci´n: Permite a un un cliente darse de baja como usuario del sistema. o
    • 5.3. Casos de Uso 40 Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: El cliente deja de estar autenticado en el sistema y deja de existir como usuario de la aplicaci´n. o Flujo b´sico: a 1 La persona quiere darse de baja del sistema. 2 El sistema muestra un aviso al cliente, y pide a este que confirme que desea darse de baja. 3 El cliente confirma que desea darse de baja. 4 El sistema procesa la baja del cliente. 5 El cliente deja de ser usuario de la aplicaci´n. o Flujo alternativo: *.1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso. 5.3.2. Casos de Uso de Gesti´n de Reservas Web o Los Casos de Uso que aqu´ se detallan son todos los relacionados con la gesti´n de las ı o reservas en el portal web del hotel por parte de los clientes. Se puede ver el diagrama correspondiente en la figura 5.2 de la p´gina 79. a 7. Hacer reserva web Actores Primarios: Cliente Descripci´n: Permite a un cliente realizar una reserva de una o varias habitaciones para un o d´ determinado. ıa Precondiciones: El cliente est´ autenticado en el sistema. a
    • 5.3. Casos de Uso 41 Postcondiciones: La reserva queda realizada a espera de que el cliente la pague. Flujo b´sico: a 1 El cliente quiere realizar una reserva de habitaci´n. o 2 La aplicaci´n pide al cliente que indique el tipo de habitaci´n que desea o o reserva, el d´ que llega, el d´ de salida, y la cantidad de habitaciones de ıa ıa ese tipo que necesita. 3 El cliente especifica todos los datos solicitados. 4 El cliente confirma que desea realizar la reserva de ese tipo de habitaci´n o para los d´ indicados. ıas 5 El sistema procesa la reserva. 6 La reserva pasa a estar realizada a la espera de ser pagada y se le muestra al cliente el n´mero de reserva para que la pueda localizar. u Flujo alternativo: *.1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso. 4.1.1 El cliente no ha introducido todos los datos. 4.1.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 4.2.1 El cliente ha introducido una fecha de llegada o de salida err´nea. o 4.2.2 El sistema indica que vuelva a introducir las fechas correctamente. y se vuelve al evento 2. 4.3.1 No hay habitaciones disponibles para los valores especificados, se indica y se vuelve al paso 2. 4.4.1 El cliente indica que desea realizar la reserva de otro tipo de habitaci´n. o 4.4.2 El sistema procesa la reserva. 4.4.3 Se vuelve al paso 2 para realizar la siguiente reserva.
    • 5.3. Casos de Uso 42 8. Consultar reservas web Actores Primarios: Cliente Descripci´n: Permite a un cliente consultar las reservas que ha realizado desde que es cliente o del hotel, se podr´n ver las reservas pagadas, las canceladas y las que est´n a´n a a u pendientes de pago. Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El cliente quiere consultar las reservas que ha realizado hasta el momento 2 El sistema muestra al cliente todas sus reservas. 9. Modificar reserva web Actores Primarios: Cliente Descripci´n: Permite a un cliente modificar una reserva realizada o Precondiciones: El cliente est´ autenticado en el sistema, y la reserva no est´ pagada ni cancea a lada. Postcondiciones: La reserva queda modificada a espera de que el cliente la pague. Flujo b´sico: a 1 El cliente quiere modificar una reserva de habitaciones. 2 El cliente indica que desea a˜adir una nueva reserva de habitaci´n. n o
    • 5.3. Casos de Uso 43 3 La aplicaci´n pide al cliente que indique el tipo de habitaci´n que desea o o reserva, el d´ que llega, el d´ de salida, y la cantidad de habitaciones de ıa ıa ese tipo que necesita. 4 El cliente especifica todos los datos solicitados. 5 El cliente confirma que desea realizar la reserva de ese tipo de habitaci´n o para los d´ indicados. ıas 6 El sistema procesa la reserva. 7 El cliente confirma que quiere guardar los cambios realizados en la reserva de habitaciones. 8 El sistema guarda la reserva. Flujo alternativo: *.1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso. 2.1 El cliente indica que desea eliminar una reserva de habitaci´n. o 2.2 El sistema pide al usuario que indique cual es la l´ ınea de reserva que desea eliminar. 2.3 El cliente especifica la l´ ınea de reserva que quiere eliminar. 2.4 El sistema procesa la eliminaci´n de la l´ o ınea de reserva. 2.5 Se pasa al paso 2 del flujo b´sico. a 5.1.1 El cliente no ha introducido todos los datos. 5.1.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 5.2.1 El cliente ha introducido una fecha de llegada o de salida err´nea. o 5.2.2 El sistema indica que vuelva a introducir las fechas correctamente. y se vuelve al evento 2. 5.3.1 No hay habitaciones disponibles para los valores especificados, se indica y se vuelve al paso 2.
    • 5.3. Casos de Uso 44 7.4.1 El cliente indica que desea seguir modificando la reserva. 7.4.2 El sistema procesa la reserva. 7.4.3 Se vuelve al paso 2 para continuar modificando 10. Consultar factura web Actores Primarios: Cliente Descripci´n: Permite a un cliente consultar la factura de cualquier reserva que haya realizado o desde que es cliente del hotel, se podr´n ver las facturas pagadas, las canceladas a y las que est´n a´n pendientes de pago. a u Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El cliente quiere consultar una factura de una reserva que ha realizado. 2 El sistema pide al cliente que indique el n´mero de reserva para la factura u que desea consultar. 3 El cliente indica el n´mero de reserva deseado. u 4 El sistema muestra al cliente la factura de la reserva solitada. En el caso de que la factura ya est´ pagada o cancelada muestra el importe que ha e pagado y si la factura est´ pendiente de pago muestra el total que debe a pagar indicando aquellos descuentos que se le han proporcionado debido a las ofertas que se le han podido aplicar. Flujo alternativo: *.1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso.
    • 5.3. Casos de Uso 45 11. Cancelar reserva web Actores Primarios: Cliente Descripci´n: Permite a un cliente cancelar cualquier reserva que haya realizado y a´n no diso u frutado, si la factura estuviese pagada se le devuelve un porcentaje del importe, dependiendo de la antelaci´n con la que la cancele. o Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: La reserva queda cancelada. Flujo b´sico: a 1 El cliente quiere cancelar una reserva que ha realizado. 2 El sistema pide al cliente que indique el n´mero de reserva que desea cancelar. u 3 El cliente indica el n´mero de reserva deseado. u 4 El sistema pide al cliente la confirmaci´n de que quiere cancelarlas. o 5 El cliente lo confirma. 6 El sistema cancela la reserva. Flujo alternativo: *.1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso. 3.1 El cliente indica un n´mero de reserva que ya hab´ sido cancelada o disu ıa frutada. 3.2 Se le muestra un error al cliente y se termina el proceso sin que se cancele ninguna reserva. 12. Pagar factura web
    • 5.3. Casos de Uso 46 Actores Primarios: Cliente Actores de Soporte: Entidad Financiera Descripci´n: Permite a un cliente pagar la factura de una reserva. o Precondiciones: El cliente est´ autenticado en el sistema. a Postcondiciones: La factura de la reserva est´ pendiente de pago y no est´ cancelada. a a Flujo b´sico: a 1 El cliente quiere pagar la factura de una reserva que ha realizado. 2 El sistema pide al cliente que indique el n´mero de reserva que desea pagar. u 3 El cliente indica el n´mero de reserva deseado. u 4 El sistema muestra al cliente la factura de la reserva y le pide la confirmaci´n o de que quiere pagarla. 5 El cliente lo confirma. 6 El sistema marca la factura como en proceso de pago y env´ los datos del ıa pago a la entidad financiera. 7 El cliente y la entidad financiera gestionan el pago de la factura. 8 La entidad financiera env´ al sistema la confirmaci´n de pago de la factura. ıa o 9 El sistema comprueba la confirmaci´n. o 10 La factura se marca como pagada. Flujo alternativo: (1-5).1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso. 3.1 El cliente indica un n´mero de reserva que ya hab´ sido pagado o que ya u ıa est´ en proceso de pago. a 3.2 Se le muestra un error al cliente y se termina el proceso sin que se pague la factura de la reserva.
    • 5.3. Casos de Uso 47 8.1 La entidad financiera no env´ la confirmaci´n de pago de la factura. ıa o 8.2 El pago de la factura se interrumpe y la factura deja de estar en proceso de pago. 5.3.3. Casos de Uso de Gesti´n de Clientes o Estos casos de uso son todos aquellos relacionados con la gestion de los Clientes, en la recepci´n del hotel, registro de nuevos clientes, consulta y modificaci´n de sus o o datos, etc. Se puede ver el diagrama correspondiente en la figura 5.3 de la p´gina 80. a 13. Buscar Cliente Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista buscar a un cliente para trabajar con ´l. o e Precondiciones: El recepcionista est´ autenticado en el sistema. a Postcondiciones: El recepcionista sigue siendo el usuario real del sistema, pero el cliente elegido es el usuario efectivo del mismo. Flujo b´sico: a 1 El recepcionista quiere buscar a un cliente para trabajar con ´l. e 2 El sistema pide al recepcionista que introduzca los par´metros requeridos a para realizar la b´squeda del cliente. u 3 El recepcionista introduce todos, algunos o ninguno de los par´metros requea ridos 4 El recepcionista confirma que desea buscar a un cliente que coincida con esos par´metros a 5 El sistema muestra todos los clientes que coinciden con los par´metros de a b´squeda y pide al recepcionista que elija a uno de ellos. u
    • 5.3. Casos de Uso 48 6 El recepcionista escoge el cliente que buscaba. 7 El sistema pone al cliente elegido como usuario efectivo del sistema. Flujo alternativo: *.1 En cualquier momento la persona tiene la posibilidad de cancelar el proceso. 14. Salir de la cuenta de un cliente Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista dejar de trabajar con la cuenta de un cliente. o Precondiciones: El recepcionista est´ autenticado en el sistema y hay un cliente como usuario a efectivo. Postcondiciones: El cliente deja de ser el usuario efectivo de la aplicaci´n. o Flujo b´sico: a 1 El recepcionista quiere salir de la cuenta de un cliente. 2 El sistema pide al recepcionista que confirme que desea salir de la cuenta del cliente. 3 El recepcionista confirma que desea salir. 4 El sistema procesa la petici´n y el cliente deja de ser el usuario efectivo de o la aplicaci´n. o Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso.
    • 5.3. Casos de Uso 49 15. Dar de Alta Cliente Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista dar de alta a un nuevo cliente en el sistema cuando o llega al hotel para realizar una reserva. Precondiciones: El recepcionista est´ autenticado en el sistema. a Postcondiciones: El nuevo cliente pasa a estar registrado en el sistema y es usuario efectivo del mismo. Flujo b´sico: a 1 El recepcionista quiere dar de alta al nuevo usuario en el sistema. 2 El sistema pide al recepcionista que introduzca los siguientes datos de los cuales algunos son obligatorios: • Nombre (obligatorio) • Apellidos (obligatorio) • DNI o pasaporte (obligatorio) • Fecha de Nacimiento (obligatorio) • Direcci´n completa (obligatorio) o • Pa´ (obligatorio) ıs • Direcci´n de e-mail (obligatorio) o • Tel´fono1 (opcional) e • Tel´fono2 (opcional) e 3 El recepcionista introduce los datos solicitados. 4 El recepcionista confirma que desea dar de alta al nuevo cliente. 5 El sistema procesa la informaci´n del nuevo cliente. o 6 El nuevo cliente pasa a estar dada de alta como cliente y es usuario efectivo del sistema en ese momento.
    • 5.3. Casos de Uso 50 Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 4.1.1 El recepcionista no ha introducido todos los datos obligatorios. 4.1.2 El sistema indica que tiene que introducir los datos obligatorios y se vuelve al evento 2 del flujo b´sico. a 4.2.1 El DNI indica que esa persona ya est´ dada de alta. a 4.2.2 Se le pide al recepcionista que compruebe que ha escrito bien el DNI y se vuelve al paso 2. 16. Modificar datos de Cliente Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista modificar los datos con los que se di´ de alta un cliente o o del sistema. Precondiciones: El recepcionista est´ autenticado en el sistema y hay un cliente como usuario a efectivo. Postcondiciones: Los datos del cliente est´n actualizados. a Flujo b´sico: a 1 El recepcionista quiere modificar los datos con los que se di´ de alta el cliente o que est´ como usuario efectivo en el sistema. a 2 El sistema muestra los datos actuales del cliente y pide al recepcionista que actualice los que desee de los siguientes: • Nombre (obligatorio) • Apellidos (obligatorio)
    • 5.3. Casos de Uso 51 • Fecha de Nacimiento (obligatorio) • Direcci´n completa (obligatorio) o • Pa´ (obligatorio) ıs • Direcci´n de e-mail (obligatorio) o • Tel´fono1 (opcional) e • Tel´fono2 (opcional) e 3 El recepcionista modifica los datos que quiere. 4 El recepcionista confirma que desea actualizar los datos del cliente. 5 El sistema procesa la actualizaci´n de los datos del cliente. o 6 Los datos del cliente pasan a estar actualizados. Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 4.1 El recepcionista no ha introducido todos los datos obligatorios. 4.2 El sistema indica que tiene que introducir los datos obligatorios y se vuelve al evento 2 del flujo b´sico. a 17. Consultar datos de Cliente Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista consultar los datos con los que se di´ de alta un cliente o o en el sistema. Precondiciones: El recepcionista est´ autenticado en el sistema y hay un cliente como usuario a efectivo. Postcondiciones: Ninguna.
    • 5.3. Casos de Uso 52 Flujo b´sico: a 1 El recepcionista quiere consultar los datos con los que se di´ de alta el cliente o que est´ como usuario efectivo en el sistema. a 2 El sistema muestra al recepcionista los datos personales del cliente. 18. Dar de baja Cliente Actores Primarios: Cliente Descripci´n: Permite al recepcionista dar de baja a un cliente como usuario del sistema. o Precondiciones: El recepcionista est´ autenticado en el sistema y hay un cliente como usuario a efectivo. Postcondiciones: El cliente deja de ser usuario efectivo del sistema y deja de existir como usuario de la aplicaci´n. o Flujo b´sico: a 1 El recepcionista quiere dar de baja del sistema al cliente que est´ como a usuario efectivo. 2 El sistema muestra un aviso al recepcionista, y pide a este que avise y confirme que el cliente desea darse de baja. 3 El recepcionista confirma que desea dar de baja al cliente. 4 El sistema procesa la baja del cliente. 5 El cliente deja de ser usuario de la aplicaci´n. o Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso.
    • 5.3. Casos de Uso 5.3.4. 53 Casos de Uso de Gesti´n de Reservas o Los Casos de Uso que aqu´ se detallan son todos los relacionados con la gesti´n de ı o las reservas en el establecimiento del hotel por parte del recepcionista a petici´n de o un cliente. Se puede ver el diagrama correspondiente en la figura 5.4 de la p´gina a 81. 19. Hacer reserva Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista realizar una reserva de una o varias habitaciones para o un d´ determinado para el cliente que lo solicite ıa Precondiciones: El recepcionista est´ autenticado en el sistema y el cliente est´ como usuario a a efectivo. Postcondiciones: La reserva queda realizada a espera de que el cliente la pague. Flujo b´sico: a 1 El recepcionista quiere realizar una reserva de habitaci´n para el cliente que o es el usuario efectivo actual de la aplicaci´n. o 2 La aplicaci´n pide al recepcionista que indique el tipo de habitaci´n que o o desea reservar, el d´ que llega el cliente, el d´ de salida, y la cantidad de ıa ıa habitaciones de ese tipo que necesita. 3 El recepcionista especifica todos los datos solicitados. 4 El recepcionista confirma que el cliente desea realizar la reserva de ese tipo de habitaci´n para los d´ indicados. o ıas 5 El sistema procesa la reserva.
    • 5.3. Casos de Uso 54 6 La reserva pasa a estar realizada a la espera de ser pagada y se le muestra al recepcionista el n´mero de reserva para que la pueda localizar y u transmit´ ırselo al cliente que ha solicitado la reserva. Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 4.1.1 El recepcionista no ha introducido todos los datos. 4.1.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 4.2.1 El recepcionista ha introducido una fecha de llegada o de salida err´nea. o 4.2.2 El sistema indica que vuelva a introducir las fechas correctamente. y se vuelve al evento 2. 4.3.1 No hay habitaciones disponibles para los valores especificados, se indica y se vuelve al paso 2. 4.4.1 El recepcionista indica que desea realizar la reserva de otro tipo de habitaci´n. o 4.4.2 El sistema procesa la reserva. 4.4.3 Se vuelve al paso 2 para realizar la siguiente reserva. 20. Consultar reservas Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista consultar las reservas que ha realizado un cliente del o hotel, se podr´n ver las reservas pagadas, las canceladas y las que est´n a´n a a u pendientes de pago. Precondiciones: El recepcionista est´ autenticado en el sistema y el cliente est´ como usuario a a efectivo.
    • 5.3. Casos de Uso 55 Postcondiciones: Ninguna. Flujo b´sico: a 1 El recepcionista quiere consultar las reservas que ha realizado el cliente hasta el momento 2 El sistema muestra al recepcionista todas las reservas del cliente. 21. Modificar reserva Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista modificar una reserva realizada por un cliente. o Precondiciones: El recepcionista est´ autenticado en el sistema, el cliente est´ como usuario a a efectivo, y la reserva no est´ pagada ni cancelada. a Postcondiciones: La reserva queda modificada a espera de que el cliente la pague. Flujo b´sico: a 1 El recepcionista quiere modificar una reserva de habitaciones por petici´n o del cliente. 2 El recepcionista indica que desea a˜adir una nueva reserva de habitaci´n. n o 3 La aplicaci´n pide al recepcionista que indique el tipo de habitaci´n que o o desea reservar, el d´ que llega el cliente, el d´ de salida, y la cantidad de ıa ıa habitaciones de ese tipo que necesita. 4 El recepcionista especifica todos los datos solicitados. 5 El recepcionista confirma que el cliente desea realizar la reserva de ese tipo de habitaci´n para los d´ indicados. o ıas 6 El sistema procesa la reserva.
    • 5.3. Casos de Uso 56 7 El recepcionista confirma que quiere guardar los cambios realizados en la reserva de habitaciones del cliente. 8 El sistema guarda la reserva. Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 2.1 El recepcionista indica que desea eliminar una reserva de habitaci´n. o 2.2 El sistema pide al recepcionista que indique cual es la l´ ınea de reserva que desea eliminar. 2.3 El recepcionista especifica la l´ ınea de reserva que quiere eliminar. 2.4 El sistema procesa la eliminaci´n de la l´ o ınea de reserva. 2.5 Se pasa al paso 2 del flujo b´sico. a 5.1.1 El recepcionista no ha introducido todos los datos. 5.1.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 5.2.1 El recepcionista ha introducido una fecha de llegada o de salida err´nea. o 5.2.2 El sistema indica que vuelva a introducir las fechas correctamente. y se vuelve al evento 2. 5.3.1 No hay habitaciones disponibles para los valores especificados, se indica y se vuelve al paso 2. 7.4.1 El recepcionista indica que desea seguir modificando la reserva. 7.4.2 El sistema procesa la reserva. 7.4.3 Se vuelve al paso 2 para continuar modificando 22. Consultar factura
    • 5.3. Casos de Uso 57 Actores Primarios: Recepcionista Descripci´n: Permite al recepcionista consultar la factura de cualquier reserva que haya o realizado un cliente del hotel, se podr´n ver las facturas pagadas, las canceladas a y las que est´n a´n pendientes de pago. a u Precondiciones: El recepcionista est´ autenticado en el sistema y el cliente est´ como usuario a a efectivo. Postcondiciones: Ninguna. Flujo b´sico: a 1 El recepcionista quiere consultar una factura de una reserva que ha realizado el cliente. 2 El sistema pide al recepcionista que indique el n´mero de reserva para la u factura que desea consultar. 3 El recepcionista indica el n´mero de reserva deseado. u 4 El sistema muestra al recepcionista la factura de la reserva solitada. En el caso de que la factura ya est´ pagada o cancelada muestra el importe que e ha pagado y si la factura est´ pendiente de pago muestra el total que debe a pagar indicando aquellos descuentos que se le han proporcionado debido a las ofertas que se le han podido aplicar. Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 23. Cancelar reserva Actores Primarios: Recepcionista
    • 5.3. Casos de Uso 58 Descripci´n: Permite al recepcionista cancelar cualquier reserva que haya realizado un cliente o y a´n no disfrutado, si la factura estuviese pagada se le devuelve al cliente un u porcentaje del importe, dependiendo de la antelaci´n con la que la cancele. o Precondiciones: El recepcionista est´ autenticado en el sistema y el cliente est´ como usuario a a efectivo. Postcondiciones: La reserva queda cancelada. Flujo b´sico: a 1 El recepcionista quiere cancelar una reserva que ha realizado el cliente. 2 El sistema pide al recepcionista que indique el n´mero de reserva que desea u cancelar. 3 El recepcionista indica el n´mero de reserva deseado. u 4 El sistema pide al recepcionista la confirmaci´n de que el cliente quiere cano celar las reservas de habitaciones de esa reserva. 5 El cliente se lo confirma y el recepcionista lo confirma al sistema. 6 El sistema cancela la reserva. Flujo alternativo: *.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 3.1 El recepcionista indica un n´mero de reserva que ya hab´ sido cancelada u ıa o disfrutada. 3.2 Se le muestra un error al recepcionista y se termina el proceso sin que se cancele ninguna reserva. 24. Pagar factura
    • 5.3. Casos de Uso 59 Actores Primarios: Recepcionista Actores de Soporte: Entidad Financiera Descripci´n: Permite al recepcionista marcar la factura de una reserva como pagada cuando o le paga el cliente. Precondiciones: El recepcionista est´ autenticado en el sistema y el cliente es el usuario efectivo. a Postcondiciones: La factura de la reserva est´ pendiente de pago y no est´ cancelada. a a Flujo b´sico: a 1 El recepcionista quiere pagar la factura de una reserva que ha realizado un cliente. 2 El sistema pide al recepcionista que indique el n´mero de reserva que desea u pagar. 3 El recepcionista indica el n´mero de reserva deseado. u 4 El sistema muestra al recepcionista la factura de la reserva y le pide la confirmaci´n de que quiere pagarla. o 5 El recepcionista indica al cliente el importe que debe pagar. 6 El cliente paga al recepcionista y el recepcionista confirma el pago. 7 El sistema procesa la confirmaci´n y marca la factura como pagada. o Flujo alternativo: (1-5).1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el proceso. 3.1 El recepcionista indica un n´mero de reserva que ya hab´ sido pagado o u ıa que ya est´ en proceso de pago. a 3.2 Se le muestra un error al recepcionista y se termina el proceso sin que se pague la factura de la reserva.
    • 5.3. Casos de Uso 60 6.1 El cliente no le paga al recepcionista. 6.2 El recepcionista cancela el pago de la factura. 5.3.5. Casos de Uso de Gesti´n de Habitaciones o Los Casos de Uso que aqu´ se detallan son todos los relacionados con la gesti´n de las ı o habitaciones en el establecimiento del hotel por parte del administrador del sistema. Se puede ver el diagrama correspondiente en la figura 5.5 de la p´gina 82. a 25. Crear Tipo de Habitaci´n o Actores Primarios: Administrador Descripci´n: Permite al administrador crear un nuevo tipo de habitaci´n en el momento o o que estime necesario, ya sea por apertura del hotel, reforma, modificaci´n de o habitaciones, etc. Los tipos de habitaciones son los que definen entre otras cosas el precio base de una habitaci´n. o Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: El nuevo tipo de habitaci´n est´ creado. o a Flujo b´sico: a 1 El administrador quiere crear un nuevo tipo de habitaci´n. o 2 La aplicaci´n pide al administrador que introduzca los siguentes datos: Deso cripci´n del tipo de habitaci´n (obligatorio), Numero de personas para o o las que est´ acondicionada la habitaci´n (obligatorio) y precio base que a o tendr´ una habitaci´n de este tipo (obligatorio). a o 3 El administrador especifica todos los datos solicitados. 4 El administrador confirma que desea crear un tipo de habitaci´n con los datos o indicados.
    • 5.3. Casos de Uso 61 5 El sistema crea el nuevo tipo de habitaci´n. o Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce todos los datos. 3.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 26. Consultar Tipo de Habitaci´n o Actores Primarios: Recepcionista, Administrador Descripci´n: Permite al administrador consultar los datos de un tipo de habitaci´n. o o Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El administrador quiere consultar los datos de un tipo de habitaci´n. o 2 El sistema pide al administrador que indique el tipo de habitaci´n que desea o consultar. 3 El administrador especifica el tipo que quiere consultar. 4 El sistema muestra al administrador el tipo de habitaci´n requerido. o Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso.
    • 5.3. Casos de Uso 62 3.1 El administrador no introduce un tipo de habitaci´n existente. o 3.2 El sistema indica que no existe el tipo de habitaci´n especificado y se vuelve o al evento 2 del flujo b´sico. a 27. Modificar Tipo de Habitaci´n o Actores Primarios: Administrador Descripci´n: Permite al administrador modificar un tipo de habitaci´n en el momento que o o estime necesario, ya sea por reforma, modificaci´n de habitaciones, etc. o Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: El tipo de habitaci´n est´ actualizado. o a Flujo b´sico: a 1 El administrador quiere modificar un tipo de habitaci´n. o 2 El sistema pide al administrador que indique el tipo de habitaci´n que desea o modificar. 3 El administrador especifica el tipo que quiere actualizar. 4 La aplicaci´n muestra al administrador los datos del tipo de habitaci´n y o o pide a este que actualice los siguentes datos: Descripci´n del tipo de habio taci´n (obligatorio), Numero de personas para las que est´ acondicionada o a la habitaci´n (obligatorio) y precio base que tendr´ una habitaci´n de este o a o tipo. 5 El administrador especifica todos los datos solicitados. 6 El administrador confirma que desea guardar los cambios realizados. 7 El sistema actualiza el tipo de habitaci´n con los nuevos datos. o Flujo alternativo:
    • 5.3. Casos de Uso 63 *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un tipo de habitaci´n existente. o 3.2 El sistema indica que no existe el tipo de habitaci´n especificado y se vuelve o al evento 2 del flujo b´sico. a 5.1 El administrador no introduce todos los datos. 5.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 4 del flujo b´sico. a 28. Crear Habitaci´n o Actores Primarios: Administrador Descripci´n: Permite al administrador crear una nueva habitaci´n en el momento que estime o o necesario, ya sea por apertura del hotel, reforma, modificaci´n de habitaciones, o etc. Los tipos de habitaciones son los que definen entre otras cosas el precio extra de una habitaci´n, y el tipo de habitaci´n. o o Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: La nueva habitaci´n est´ creada. o a Flujo b´sico: a 1 El administrador quiere crear una nueva habitaci´n. o 2 La aplicaci´n pide al administrador que introduzca los siguentes datos: Tio po de habitaci´n (obligatorio), Numero de habitaci´n (obligatorio), piso o o en el que est´ la habitaci´n y precio extra que tendr´ esta habitaci´n en a o a o particular. 3 El administrador especifica todos los datos solicitados.
    • 5.3. Casos de Uso 64 4 El administrador confirma que desea crear una habitaci´n con los datos ino dicados. 5 El sistema crea la nueva habitaci´n. o Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce todos los datos. 3.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 29. Consultar Habitaci´n o Actores Primarios: Recepcionista, Administrador Descripci´n: Permite al administrador consultar los datos de una habitaci´n. o o Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El administrador quiere consultar los datos de una habitaci´n. o 2 El sistema pide al administrador que indique el n´mero de la habitaci´n que u o desea consultar. 3 El administrador especifica el n´mero de habitaci´n que quiere consultar. u o 4 El sistema muestra al administrador los datos de la habitaci´n requerida. o Flujo alternativo:
    • 5.3. Casos de Uso 65 *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de habitaci´n existente. u o 3.2 El sistema indica que no existe la habitaci´n especificada y se vuelve al o evento 2 del flujo b´sico. a 30. Modificar Habitaci´n o Actores Primarios: Administrador Descripci´n: Permite al administrador modificar una habitaci´n en el momento que estime o o necesario, ya sea por reforma, etc. Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: La habitaci´n est´ actualizada. o a Flujo b´sico: a 1 El administrador quiere modificar los datos de una habitaci´n. o 2 El sistema pide al administrador que indique el n´mero de la habitaci´n que u o desea modificar. 3 El administrador especifica el n´mero de la habitaci´n que quiere actualizar. u o 4 La aplicaci´n muestra al administrador los datos de la habitaci´n y pide o o a este que actualice los siguentes datos: Tipo de habitaci´n (obligatorio), o Numero de la habitaci´n (obligatorio), piso (obligatorio) y precio extra que o tendr´ esta habitaci´n en particular. a o 5 El administrador especifica todos los datos solicitados. 6 El administrador confirma que desea guardar los cambios realizados. 7 El sistema actualiza la habitaci´n con los nuevos datos. o
    • 5.3. Casos de Uso 66 Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de habitaci´n existente. u o 3.2 El sistema indica que no existe la habitaci´n especificada y se vuelve al o evento 2 del flujo b´sico. a 5.1 El administrador no introduce todos los datos. 5.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 4 del flujo b´sico. a 31. Registrar Incidencia de Habitaci´n o Actores Primarios: Administrador Descripci´n: Permite al administrador registrar alguna incidencia que haya tenido lugar en o una de las habitaciones del hotel. Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: La incidencia queda registrada y asociada a la habitaci´n pertinente. o Flujo b´sico: a 1 El administrador quiere registrar una nueva incidencia. 2 El sistema pide al administrador que indique el n´mero de la habitaci´n a la u o cual desea asociar la incidencia. 3 El administrador especifica el n´mero de la habitaci´n que requerido. u o 4 La aplicaci´n pide al administrador que introduzca los siguentes datos: Tipo o de incidencia (obligatorio): grave, leve, etc, y una descripci´n textual de lo o ocurrido. 5 El administrador especifica todos los datos solicitados.
    • 5.3. Casos de Uso 67 6 El administrador confirma que desea registrar la incidencia. 7 El sistema registra la incidencia asociada a la habitaci´n que procede. o Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de habitaci´n existente. u o 3.2 El sistema indica que no existe la habitaci´n especificada y se vuelve al o evento 2 del flujo b´sico. a 5.1 El administrador no introduce todos los datos. 5.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 4 del flujo b´sico. a 32. Consultar Incidencias de Habitaci´n o Actores Primarios: Administrador Descripci´n: Permite al administrador consultar todas las incidencias que hayan tenido lugar o en una de las habitaciones del hotel. Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El administrador quiere consultar las incidencias de una habitaci´n. o 2 El sistema pide al administrador que indique el n´mero de la habitaci´n de u o la cual desea consultar las incidencias. 3 El administrador especifica el n´mero de la habitaci´n que requerido. u o
    • 5.3. Casos de Uso 68 4 El sistema muestra al administrador todas las incidencias ocurridas en esa habitaci´n. o Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de habitaci´n existente. u o 3.2 El sistema indica que no existe la habitaci´n especificada y se vuelve al o evento 2 del flujo b´sico. a 5.3.6. Casos de Uso de Gesti´n de Ofertas o Los Casos de Uso que aqu´ se detallan son todos los relacionados con la gesti´n de ı o las ofertas en el establecimiento del hotel por parte del administrador del sistema. El administrador es el engargado de dar de alta nuevas ofertas y tiene la responsabilidad de especificar correctamente qu´ ofertas son incompatibles con qu´ otras, y las reglas e e de aplicaci´n por las que se regir´n, estas reglas definir´n el contexto en el cual una o a a oferta se podr´ aplicar. Se puede ver el diagrama correspondiente en la figura 5.6 de a la p´gina 83. a 33. Crear Tipo de Oferta Actores Primarios: Administrador Descripci´n: Permite al administrador crear un nuevo tipo de oferta en el momento que o estime necesario. Los tipos de oferta son los que definen entre otras cosas a qu´ se podr´ aplicar la oferta, reservas de habitaciones, servicios extra, etc, y e a con qu´ otros tipos de oferta ser´ incompatible. e a Precondiciones: El administrador est´ autenticado en el sistema. a
    • 5.3. Casos de Uso 69 Postcondiciones: El nuevo tipo de oferta est´ creado. a Flujo b´sico: a 1 El administrador quiere crear un nuevo tipo de oferta. 2 La aplicaci´n pide al administrador que introduzca los siguentes datos: Nomo bre para el tipo de oferta (obligatorio), Descripci´n del tipo de oferta (oblio gatorio), A qu´ se podr´ aplicar este tipo de oferta (obligatorio) y cantidad e a m´ ınima (obligatorio), y con qu´ otros tipos de oferta ser´ incompatible este e a nuevo tipo. 3 El administrador especifica todos los datos solicitados. 4 El administrador confirma que desea crear un tipo de oferta con los datos indicados. 5 El sistema crea el nuevo tipo de oferta. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce todos los datos obligatorios. 3.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 34. Consultar Tipo de Oferta Actores Primarios: Administrador Descripci´n: Permite al administrador consultar los datos de un tipo de oferta. o Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: Ninguna.
    • 5.3. Casos de Uso 70 Flujo b´sico: a 1 El administrador quiere consultar los datos de un tipo de oferta. 2 El sistema pide al administrador que indique el tipo de oferta que desea consultar. 3 El administrador especifica el tipo que quiere consultar. 4 El sistema muestra al administrador los datos del tipo de oferta requerido. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un tipo de oferta existente. 3.2 El sistema indica que no existe el tipo de oferta especificado y se vuelve al evento 2 del flujo b´sico. a 35. Modificar Tipo de Oferta Actores Primarios: Administrador Descripci´n: Permite al administrador modificar un tipo de oferta en el momento que estime o necesario. Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: El tipo de oferta est´ actualizado. a Flujo b´sico: a 1 El administrador quiere modificar un tipo de oferta. 2 El sistema pide al administrador que indique el tipo de habitaci´n que desea o modificar.
    • 5.3. Casos de Uso 71 3 El administrador especifica el tipo que quiere actualizar. 4 La aplicaci´n muestra al administrador los datos del tipo de oferta y pide a o este que actualice los siguentes datos: Nombre para el tipo de oferta (obligatorio), Descripci´n del tipo de oferta (obligatorio), A qu´ se podr´ aplicar o e a este tipo de oferta (obligatorio) y cantidad m´ ınima (obligatorio), y con qu´ otros tipos de oferta ser´ incompatible este tipo. e a 5 El administrador especifica todos los datos solicitados. 6 El administrador confirma que desea guardar los cambios realizados. 7 El sistema actualiza el tipo de oferta con los nuevos datos. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un tipo de oferta existente. 3.2 El sistema indica que no existe el tipo de oferta especificado y se vuelve al evento 2 del flujo b´sico. a 5.1 El administrador no introduce todos los datos obligatorios. 5.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 4 del flujo b´sico. a 36. Crear Oferta Actores Primarios: Administrador Descripci´n: Permite al administrador crear una nueva oferta en el momento que estime o necesario, ya sea por apertura del hotel, eventos especiales, etc. Las Ofertas son las que definen entre otras cosas a qui´n se le podr´ aplicar una oferta gracias e a a las reglas que se pueden definir, fechas de aplicaci´n, etc. o
    • 5.3. Casos de Uso 72 Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: La nueva oferta est´ creada pero como un borrador que luego habr´ que revisar a a y publicar. Flujo b´sico: a 1 El administrador quiere crear una nueva oferta. 2 La aplicaci´n pide al administrador que introduzca los siguentes datos: Tio po de oferta (obligatorio), Fecha en la que se comenzar´ y terminar´ la a a aplicaci´n de la oferta (obligatorio), Descuento que ofrece esta oferta (obio gatorio), Descripci´n de la oferta (obligatorio) y regla que ser´ utilizada o a por el sistema a la hora de saber si una oferta se puede aplicar en ciertas condiciones especiales (obligatorio). 3 El administrador especifica todos los datos solicitados. 4 El administrador confirma que desea crear una oferta con los datos indicados. 5 El sistema crea la nueva oferta y se marca como borrador no publicado. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce todos los datos. 3.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 2 del flujo b´sico. a 37. Consultar Oferta Actores Primarios: Administrador Descripci´n: Permite al administrador consultar los datos de una oferta. o
    • 5.3. Casos de Uso 73 Precondiciones: El administrador est´ autenticado en el sistema. a Postcondiciones: Ninguna. Flujo b´sico: a 1 El administrador quiere consultar los datos de una oferta. 2 El sistema pide al administrador que indique el n´mero de la oferta que desea u consultar. 3 El administrador especifica el n´mero de oferta que quiere consultar. u 4 El sistema muestra al administrador los datos de la oferta requerida. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de oferta existente. u 3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento 2 del flujo b´sico. a 38. Modificar Oferta Actores Primarios: Administrador Descripci´n: Permite al administrador modificar una oferta en el momento que estime neceo sario, ya sea por reforma, etc, siempre y cuando esta oferta a´n sea un borrador. u Precondiciones: El administrador est´ autenticado en el sistema y la oferta a´n est´ marcada a u a como borrador y no ha sido publicada. Postcondiciones: La oferta est´ actualizada. a
    • 5.3. Casos de Uso 74 Flujo b´sico: a 1 El administrador quiere modificar los datos de una oferta. 2 El sistema pide al administrador que indique el n´mero de la oferta que desea u modificar. 3 El administrador especifica el n´mero de la oferta que quiere actualizar. u 4 La aplicaci´n muestra al administrador los datos de la oferta y pide a este que o actualice los siguentes datos: Tipo de oferta (obligatorio), Fecha en la que se comenzar´ y terminar´ la aplicaci´n de la oferta (obligatorio), Descuento a a o que ofrece esta oferta (obigatorio), Descripci´n de la oferta (obligatorio) y o regla que ser´ utilizada por el sistema a la hora de saber si una oferta se a puede aplicar en ciertas condiciones especiales (obligatorio). 5 El administrador especifica todos los datos solicitados. 6 El administrador confirma que desea guardar los cambios realizados. 7 El sistema actualiza la oferta con los nuevos datos. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de oferta existente. u 3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento 2 del flujo b´sico. a 5.1 El administrador no introduce todos los datos. 5.2 El sistema indica que tiene que especificar todos los datos y se vuelve al evento 4 del flujo b´sico. a 39. Eliminar Oferta
    • 5.3. Casos de Uso 75 Actores Primarios: Administrador Descripci´n: Permite al administrador eliminar una oferta que estaba como borrador. o Precondiciones: El administrador est´ autenticado en el sistema, la oferta no est´ publicada y a a est´ marcada como borrador. a Postcondiciones: La oferta est´ eliminada y deja de existir. a Flujo b´sico: a 1 El administrador quiere eliminar una oferta. 2 El sistema pide al administrador que indique el n´mero de la oferta que desea u eliminar. 3 El administrador especifica el n´mero de oferta requerido. u 4 La aplicaci´n pide al administrador la confirmaci´n de que desea eliminar la o o oferta indicada. 5 El administrador confirma que desea eliminar la oferta. 6 El sistema elimina la oferta. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de oferta existente. u 3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento 2 del flujo b´sico. a 40. Publicar Oferta Actores Primarios: Administrador
    • 5.3. Casos de Uso 76 Descripci´n: Permite al administrador publicar una oferta para que la puedan disfrutar los o clientes. Precondiciones: El administrador est´ autenticado en el sistema y la oferta no est´ publicada. a a Postcondiciones: La oferta queda publicada. Flujo b´sico: a 1 El administrador quiere publicar una oferta. 2 El sistema pide al administrador que indique el n´mero de la oferta que desea u publicar. 3 El administrador especifica el n´mero la oferta requerido. u 4 La aplicaci´n pide al administrador la confirmaci´n de que desea publicar la o o oferta indicada. 5 El administrador confirma que desea publicar la oferta. 6 El sistema publica la oferta. Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de oferta existente. u 3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento 2 del flujo b´sico. a 41. Dar de baja Oferta Actores Primarios: Administrador
    • 5.3. Casos de Uso 77 Descripci´n: Permite al administrador dar de baja una oferta. Esto es un mecanismo de o seguridad por si se public´ una oferta por error o descuido que pueda afectar o gravemente a la econom´ del establecimiento. ıa Precondiciones: El administrador est´ autenticado en el sistema y la oferta est´ publicada. a a Postcondiciones: La oferta deja de estar publicada. Flujo b´sico: a 1 El administrador quiere dar de baja una oferta. 2 El sistema pide al administrador que indique el n´mero de la oferta que desea u dar de baja. 3 El administrador especifica el n´mero de oferta requerido. u 4 El sistema pide al administrador la confirmaci´n de que desea dar de baja la o oferta indicada. 5 El administrador confirma que desea dar de baja la oferta. 6 El sistema da de baja la oferta y de esta forma deja de estar publicada para el p´blico. u Flujo alternativo: *.1 En cualquier momento el administrador tiene la posibilidad de cancelar el proceso. 3.1 El administrador no introduce un n´mero de oferta existente. u 3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento 2 del flujo b´sico. a
    • 5.4. Modelo de Casos de Uso 5.4. 5.4.1. Modelo de Casos de Uso Gesti´n de Usuarios Web o Figura 5.1: Diagrama de Casos de Uso de Gesti´n de Usuarios Web o 78
    • 5.4. Modelo de Casos de Uso 5.4.2. Gesti´n de Reservas Web o Figura 5.2: Diagrama de Casos de Uso de Gesti´n de Reservas Web o 79
    • 5.4. Modelo de Casos de Uso 5.4.3. Gesti´n de Clientes o Figura 5.3: Diagrama de Casos de Uso de Gesti´n de Clientes o 80
    • 5.4. Modelo de Casos de Uso 5.4.4. Gesti´n de Reservas o Figura 5.4: Diagrama de Casos de Uso de Gesti´n de Reservas o 81
    • 5.4. Modelo de Casos de Uso 5.4.5. Gesti´n de Habitaciones o Figura 5.5: Diagrama de Casos de Uso de Gesti´n de Habitaciones o 82
    • 5.4. Modelo de Casos de Uso 5.4.6. Gesti´n de Ofertas o Figura 5.6: Diagrama de Casos de Uso de Gesti´n de Ofertas o 83
    • Cap´ ıtulo 6 Dise˜o de la aplicaci´n n o 6.1. Arquitectura General Para el desarrollo de este proyecto se va a seguir el patr´n arquitect´nico Modelo-Vistao o Controlador cuyo objetivo es desligar el dise˜o de las interfaces de usuario del resto del n sistema. Hoy en d´ es la t´cnica habitual de dise˜o de interfaces en la programaci´n ıa e n o Web con J2EE. Con esta t´cnica se consiguen principalmente dos cosas: que el modelo e sea reusable con distintas vistas, lo que es una ventaja si el d´ de ma˜ana se quiere ıa n realizar una interfaz gr´fica local; y gracias a que se desarrolla de esta forma el software, a se puede dividir el trabajo de forma clara dentro de un equipo, seg´n la especialidad de u cada miembro. Pero la arquitectura mejora cuando se usan conjuntamente con el patr´n arquitect´nico o o Layers. Usando esta arquitectura el software se estructura en capas de forma que un cambio en una de ellas, o incluso el reemplazo, no produce un cambio en capas superiores. El Modelo Es una abstracci´n que representa a los objetos de la aplicaci´n que se o o est´ desarrollando, en esta capa se incluyen tanto los datos (Bases de Datos, Ficheros, a 85
    • 6.1. Arquitectura General 86 etc) como las reglas de negocio (el comportamiento que debe tener la aplicaci´n). No tiene o conocimiento de ninguna de las otra dos partes, vista y controlador. La Vista El la capa encargada de la representaci´n visual de los datos del modelo, para o ello necesita acceder al modelo para obtener los datos que tiene que mostrar al usuario final. El Controlador El controlador es el encargado de recoger las acciones que el usuario efect´a sobre la vista, para a continuaci´n invocar las acciones pertinentes del modelo, u o normalmente, y as´ es en este caso, es el unico que conoce a las otras dos capas, modelo y ı ´ vista. A continuaci´n (figura 6.1) se muestra un peque˜o esquema de c´mo se va a dividir el o n o sistema que se est´ desarrollando con algunos de los subsitemas que se pueden encontrar a en cada una de las capas. Figura 6.1: Arquitectura General Del Sistema (Modelo-Vista-Controlador)
    • 6.2. Capa de la Vista 87 En las siguientes secciones se explica cada una de estas tres capas en detalle, qu´ contiene, e qu´ objetivos se persiguen, patrones y tecnolog´ utilizados. e ıas 6.2. Capa de la Vista La capa vista incluye todos aquellos paquetes y artefactos necesarios para la presentaci´n o gr´fica. En esta capa se incluyen las p´ginas JSP y los objetos que estas necesitan para a a una correcta representaci´n de los datos. o En esta capa se usa la tecnolog´ JSP que permite escribir p´ginas web usando c´digo ıa a o java, pero, para no incluir c´digo java en las p´ginas web de este proyecto, se usar´ el API o a a de JSTL que permite ocultar todo el c´digo java mediante etiquetas ya predefinidas. De o esta forma se consigue que en un futuro un dise˜ador gr´fico pueda dise˜ar la forma que n a n deben tener las p´ginas sin tener que saber nada sobre el lenguaje de programaci´n Java. a o Como se puede observar en la figura 6.2, esta capa se divide en dos partes bien diferenciadas, una de ellas es la que contiene las p´ginas JSP y la otra es d´nde est´n ubicados a o a los recursos java que estas p´ginas necesitan para poder mostrar su contenido. a Figura 6.2: Arquitectura de la Capa Vista
    • 6.2. Capa de la Vista 6.2.1. 88 Hojas de Estilo - CSS El estilo de la interfaz web de usuario lo definen unas hojas de estilo creadas para tal efecto, de esta forma, las p´ginas JSP que se explicar´n a continuaci´n s´lo tienen que a a o o definir la estructura general y el contenido, dejando toda la parte de presentaci´n para la o hoja de estilos. Los estilos se han definido todos tomando como base un estilo css libre y se ha adaptado totalmente para que la relaci´n de tama˜os se hiciese de forma relativa y no absoluta, esto o n se consigue adaptando todos los tama˜os y posiciones, expres´ndolos de forma porcentual. n a Con esto se consigue que, sea cual sea la resoluci´n del ordenador desde el que se visualice o la aplicaci´n, esta no tenga unas dimensiones fijas, sino que se adapte a las dimensiones o del navegador. 6.2.2. P´ginas JSP a Para la presentaci´n mediante p´ginas JSP se usa un sistema de plantillas, as´ simpleo a ı mente hay que definir la apariencia global de un grupo de p´ginas y todas aquellas que a extiendan esa plantilla tendr´n una apariencia similar. En el caso de este proyecto, se a consider´ que al haber tres tipos de usuarios bien diferenciados, ser´ una buena idea que o ıa hubiese tres plantillas distintas para diferenciar claramente qu´ tipo de usuario est´ en la e a aplicaci´n en cada momento. o A su vez dentro de cada plantilla hay dos opciones de presentaci´n, que se diferencian o usando luego hojas de estilo en cascada (CSS). Por un lado est´n las p´ginas que s´lo a a o muestran informaci´n, y aquellas que adem´s de mostra informaci´n tienen una barra o a o lateral que permite escoger la operaci´n que se desea realizar. En el caso que nos ocupa o se usa el sistema de plantillas Tiles de Struts. Adem´s Struts nos proporciona un sistema mediante el cual mostrar y recoger datos de a formularios se realiza de forma m´s sencilla. Este sistema lo proporcionan los servlet y los a
    • 6.2. Capa de la Vista 89 ActionForms que define el programador y cuyo funcionamiento se detalla en una secci´n o posterior. 6.2.2.1. Sistema de Plantillas Tiles de Struts Gracias a este sistema de plantillas se pueden definir todas las pantallas de una aplicaci´n o web en un fichero XML. Despu´s de tener las pantallas definidas, se pueden usar tags e predefinidos para recuperar lo que se necesite: t´ ıtulo, enlaces, etc. En primer lugar hay que definir una pantalla base por cada conjunto de ventanas. Esta pantalla base especifica la p´gina JSP que contiene la estructura b´sica de este conjunto a a de ventanas y todo aquello que es com´n a todas ellas. u Luego para definir cada una de las distintas pantallas, simplemente se extiende de la pantanlla base deseada y se ponen los valores propios de la ventana que se desea mostrar. En la figura 6.3 se pueden ver dos plantillas que posteriormente puede derivar en dos ventanas diferentes dependiento de los valores con los que se extienda la pantalla base. La estructura b´sica de cada grupo de pantallas se define en una p´gina JSP que se a a llama DefaultLayout.jspx y las partes comunes se especificar´n en DefaultFooter.jspx y a DefaultTitle.jspx. Figura 6.3: Plantilla de una ventana
    • 6.2. Capa de la Vista T´ ıtulo 90 Es la zona donde ir´ el nombre de la empresa y el t´ a ıtulo de la parte de la aplicaci´n o en la que se est´ trabajando. a Cabezera Aqu´ se mostrar´ una peque˜a descripci´n de la operaci´n en curso que se ı a n o o muestra en la parte de Contenido. Contenido Aqu´ se mostrar´ el resultado de la operaci´n solicitada por el usuario: ı a o tablas, formularios, im´genes, etc. a Men´ En esta zona se posicionar´n los enlaces a las distintas operaciones que el usuario u a puede realizar. Pie de p´gina a Este es el lugar donde se pondr´ el nombre del desarrollador, licencia a bajo la que est´ publicado el software, pol´ a ıtica de privacidad, etc. Una vez terminada la aplicaci´n, el resultado no tiene nada que ver con rect´ngulos o a como se observ´ en la figura anterior, sino que quedar´ algo como lo que se muestra en o ıa la siguiente imagen. Figura 6.4: Resultado Final de una ventana
    • 6.2. Capa de la Vista 6.2.3. 91 ActionForms Un ActionForm es simplemente un Bean que contiene las funcionalidades b´sicas de un a formulario, entrada y recuperaci´n de los datos de cada campo, y adem´s proporciona, si o a es necesario, una validaci´n de los datos a la hora del procesamiento de los mismos. o Definir un ActionForm es muy sencillo, simplemente hay que heredar de la clase ActionForm que proporciona Struts y luego el Objeto que se est´ construyendo debe contener a m´todos Get y Set para todos los campos del formulario. Luego para trabajar con este e Objeto hay que especificar en el fichero de configuraci´n de Struts donde se encuentra el o objeto y a la hora de usarlo en una acci´n simplemente se tiene que indicar que se va a o utilizar dicho objeto y si se desea que se valide el contenido antes de pas´rselo a la acci´n. a o En la p´gina JSP cuando dentro de una etiqueta ’<form>’ se desea especificar que un a campo determinado, va a ser un campo del objeto ActionForm que se ha definido para ese formulario, simplemente se le a˜ade a la etiqueta correspondiente el atributo ’property’ n con el valor del nombre exacto del atributo del ActionForm que lo define. A partir de aqu´ ya se encarga Struts de manejar el formulario y de pasarle a la acci´n que lo gestiona, ı o el ActionForm que corresponda, de forma que en la acci´n de Struts se puede recuperar o de forma sencilla el valor del formulario, o viceversa, introducir datos previamente en un formulario antes de que sea mostrado. 6.2.4. Internacionalizaci´n o Internacionalizar una aplicaci´n consiste en que esta sea accesible y funcione correctao mente sea cual sea el pa´ e idioma donde se utiliza el sistema. Localizar una aplicaci´n no ıs o es simplemente que los textos aparezcan en otro idioma, sin´ que tambi´n hay que tener o e en cuenta otros detalles como por ejemplo la representaci´n de n´meros, porcentajes o o u fechas. Ya que en pa´ ıses como Gran Breta˜a los decimales se representan con un punto n como separador mientras que en Espa˜a se indica con una coma. n
    • 6.2. Capa de la Vista 92 En un sistema como el que se est´ desarrollando es obligatoria la intenacionalizaci´n. a o En otras aplicaciones es aconsejable, pero en esta no puede faltar ya que al tratarse de una aplicaci´n para un hotel, que esta estea internacionalizada permite que el sistema sea o accesible para gente de muchos pa´ ıses. La internacionalizaci´n de aplicaciones web empresariales con p´ginas JSP es muy seno a cilla utilizando las etiquetas que nos proporciona la librer´ JSTL. Lo m´s complicado es ıa a integrar la localizaci´n de JSTL con la que proporciona Struts ya que, entre otras cosas, o utilizan procesos distintos para localizar las traducciones. La librer´ de JSTL proporciona ıa las etiquetas ’<fmt:xxxxxx/>’ que sirven proporcionan formas sencillas para especificar mensajes, ya que s´lo hay que indicar la clave correspondiente del fichero de mensajes, o adem´s estas etiquetas proporcionan m´todos simples para internacionalizar n´meros dea e u cimales, porcentajes o las distintas fechas. Lo primero que hay que hacer es especificar en los distintos ficheros de configuraci´n o c´mo se llaman los archivos que contienen las traducciones. Las traducciones dentro de o estos ficheros tienen la forma clave=valor. En este caso los ficheros tendr´n como noma bre Messages.properties la traducci´n b´sica por defecto que estar´ en ingl´s y Messao a a e ges ll CC.properties las dem´s traducciones donde ’ll’ es el c´digo de idioma y ’CC’ el a o c´digo de pa´ que identifican un´ o ıs ıvocamente la traducci´n. Los c´digos de los idiomas o o est´n definidos en el est´ndar ISO 639 y los c´digos de los pa´ en el est´ndar ISO 3166. a a o ıses a Cuando se inicia la aplicaci´n esta coge como idioma el mismo que tiene el navegador o del cliente, si no se puede identificar entonces se tomar´ el idioma del servidor web, y si a tampoco se puede identificar o el idioma a´n no est´ soportado, entonces se escoger´ el u a a idioma por defecto. Una vez dentro del sistema el usuario, sea cual sea, tiene la posibilidad de elegir el idioma que desee de entre todos los disponibles. En el proyecto que se est´ realizando, esta internacionalizaci´n se realizar´ en tres idioa o a mas: Gallego, Castellano e Ingl´s. Con estos tres idiomas se puede acceder a much´ e ısimos
    • 6.3. Capa del Controlador 93 millones de personas. Aunque ser´ muy sencillo realizar nuevas traducciones para otros a idiomas, simplemente se crea un nuevo fichero con los c´digos de idioma y pa´ deseao ıs dos, y se cambian las traducciones actuales por las correctas para el idioma que se quiera traducir. 6.2.5. ApplicationObjects Los ApplicationObjects son objetos de utilidad que utiliza la capa vista para la representaci´n de algunos datos, en el caso de este proyecto se necesitaba por ejemplo de un o objeto que sirviera para mostrar las fechas, algo muy util ya que la utilizaci´n de fechas ´ o es muy com´n entre muchos de los casos de uso que se implementan. Esta clase se llama u DateRanges, se ha aprovechado de la implentaci´n de un ejemplo que distribuyeron en la o asignatura de IS de quinto curso de Ingenier´ Inform´tica. ıa a Por otro lado tambi´n se vio la necesidad de una clase que sirviera de cach´ para mostrar e e los tipos de habitaci´n que hay en el sistema. Como los tipos de habitaci´n se utilizan o o mucho, ser´ muy ineficiente consultarlos en la base de datos cada vez que se quisieran ıa mostrar. Por eso, esta clase guarda en memoria todos los tipos de habitaci´n tan pronto o como la clase es cargada en memoria. La poca memoria que se desperdicia se compensa por la eficiencia que se gana con el ahorro en accesos a la base de datos. 6.3. Capa del Controlador La capa del controlador es la que contiene aquellos paquetes y artefactos necesarios para la separaci´n de la vista y del modelo. Para el dise˜o de esta capa se utilizan una serie de o n patrones arquitect´nicos que se muestran a continuaci´n en las siguientes secciones. o o En esta capa es en la que se centra principalmente Struts, proporcionando todas las implementaciones b´sicas que se necesitan para el desarrollo de una aplicaci´n web ema o presarial.
    • 6.3. Capa del Controlador 6.3.1. 94 Patr´n Front Controller o El patr´n Front Controller consiste en que, cada vez que el servidor recibe una nueva o petici´n siempre la procesa el mismo controlador, que lo unico que hace es delegar en otras o ´ clases para que resuelvan la petici´n. Para esto struts proporciona la clase ActionServlet o que luego hay que extender para a˜adirle nuevas funcionalidades personalizadas como n filtros de procesado. Lo primero que se hace es indicar en el fichero de configuraci´n del servidor, que todas o las peticiones que terminen en ’.do’ las procese el nuevo Servlet que se ha definido. Para decirle al servidor que todas estas peticiones vayan al servlet personalizado, simplemente hay que especificar el patr´n que siguen (en este caso *.do) y a continuaci´n especificar el o o nombre de la clase que extiende ActionServlet. En la figura 6.5 podemos ver como se esctructuran las distintas clases que dan forma a este patr´n. o
    • 6.3. Capa del Controlador 95 javax.servlet.http.HttpServlet org.apache.struts.action.ActionServlet org.apache.struts.action.Action 1 #doGet() #doPost() 0..* +execute() Action1 ActionN <<instantiate>> <<call>> org.apache.struts.action.ActionForm +reset() +validate() <<call>> ActionForm1 ActionFormN Figura 6.5: Patr´n Front Controller General o Ahora vamos a describir c´mo se relacionan las clases que se ven en el diagrama anterior. o Cuando el servidor web recibe una petici´n comprueba si la URL solicitada cumple o alguno de los patrones que se especifican en su fichero de configuraci´n web.xml, si es as´ o ı, entonces crea una instancia del ActionServlet que tiene indicado para manejar esa petici´n. o En el caso del proyecto que se est´ desarrollando, el ActionServlet que gestionar´ las a a peticiones de URLs terminadas en ’.do’ ser´ HotelPortalRequestProcessor. En este caso a no se va a extender del ActionServlet de Struts sino que se hace de TilesRequestProcessor, como ya se ha visto, el plugin Tiles para Struts se encarga de construir las ventanas a partir de unas plantillas, por eso se deja que primero la petici´n pase por el procesador de Tiles. o A continuaci´n el HotelPortalRequestProcessor tiene que llamar a la acci´n que se ha o o especificado para gestionar la URL en concreto que le ha llegado. Adem´s entre otras cosas a
    • 6.3. Capa del Controlador 96 a la acci´n que se va a invocar se le pasar´, en caso de que hubiese alguno, el formulario o a asociado a esa acci´n (ActionForm). o Si s´lo se quisiera la funcionalidad que se acaba de mencionar, no har´ falta crear un o ıa procesador de acciones propio, valdr´ de igual forma el procesador de acciones de Tiles. ıa Pero como el sistema que se esta desarrollando es algo complejo, se necesita de algo m´s. a En primer lugar se va a necesitar mantener las sesiones de los usuarios activas y cuando un usuario haga una petici´n, ser´ indispensable comprobar que este est´ autenticado en o a a la aplicaci´n. o Adem´s es tambi´n una buena idea que en este momento de la petici´n, cuando a´n a e o u no se ha hecho nada importante, se comprobase si el usuario que est´ autenticado en a la aplicaci´n tiene acceso a la acci´n que intenta llevar a cabo, y si no es as´ no se le o o ı permitir´ realizarla. a Implementar este tipo de controles no es tarea f´cil, por lo tanto se busca alg´n tipo de a u patr´n que pueda ayudar a resolver esta cuesti´n. El patr´n que se usar´ ser´ el llamado o o o a a Chain of Responsability (Cadena de Responsabilidad) a trav´s de una cadena de filtros, por e los cuales pasar´ la petici´n, si en el contexto en el que se est´ se cumplen las condiciones a o a de todos los filtros entonces la petici´n seguir´ adelante. o a 6.3.2. Patr´n Chain of Responsability o Este patr´n, Cadena de Responsabilidad, utiliza la delegaci´n como proceso b´sico para o o a realizar su cometido. En este caso se usa una cadena de filtros por la cual pasa la petici´n o inicial. Esta cadena funciona de la siguiente forma. La petici´n entra en el primer filtro, este comprueba si se cumple alguna de las condio ciones preestablecidas para las que tiene una respuesta ya predefinida, es decir, que con la informaci´n que tiene el filtro ya puede decir qu´ acci´n se tiene que ejecutar luego. Si o e o ninguna de las condiciones del filtro se cumple, entonces este delega toda la responsabili-
    • 6.3. Capa del Controlador 97 dad en el siguiente filtro de la cadena, el cual realiza el mismo proceso, y as´ hasta que se ı termine la cadena de filtros. En la aplicaci´n de este proyecto se usan cuatro filtros a trav´s de los cuales deben pasar o e todas las peticiones. Estos filtros son los que se muestran a continuaci´n, por orden de o aplicaci´n. o SessionPreProcessingFilter Este filtro lo primero que hace es comprobar si la sesi´n o del usuario a´n est´ activa, en caso afirmativo no hace nada. Si la sesi´n ha terminado u a o tiene que comprobar si el usuario tiene su nombre y contrase˜a guardadas en las cookies, n y si es as´ reestablecerle la sesi´n. A diferencia de otros filtros, este filtro no interrumpe la ı o ejecuci´n de la cadena, simplemente sirve para que en todas las peticiones se est´ compleo e temente seguro de que la sesi´n est´ activa. o a AuthenticationPreProcessingFilter Este es uno de los filtros m´s importantes ya a que es el encargado de verificar si el usuario que est´ utilizando la aplicaci´n est´ aua o a tenticado o no. En caso de que lo est´ no hace nada y ejecuta el siguiente filtro de la e cadena, pero si el usuario no est´ autenticado, tiene que comprobar si la acci´n que quiere a o realizar requiere de autenticaci´n, de ser as´ este filtro enviar´ al usuario a la p´gina de o ı ıa a autenticaci´n. o AdminOnlyPreProcessingFilter El filtro AdminOnly proporciona una comprobaci´n o de acceso, al estar despu´s del filtro que comprueba si el usuario est´ autenticado, ya se e a sabe que el usuario est´ autenticado, por lo que este filtro tiene la misi´n de chequear si la a o acci´n que se desea realizar es una acci´n que s´lo puede realizar el administrador, de ser o o o as´ el filtro debe comprobar que el usuario que solicita la acci´n es el administrador, una ı o vez realizada esta comprobaci´n, si el usuario es el administrador entonces se le permite o realizar la operaci´n, y si no lo es se le env´ a la p´gina principal. o ıa a
    • 6.3. Capa del Controlador RecepcionistOnlyPreProcessingFilter 98 Este filtro proporciona otra comprobaci´n de o acceso, al estar despu´s del filtro que comprueba si el usuario est´ autenticado, ya se sabe e a que el usuario est´ autenticado, por lo que este filtro tiene la misi´n de chequear si la a o acci´n que se desea realizar es una acci´n que s´lo puede realizar el recepcionista, de ser o o o as´ el filtro debe comprobar que el usuario que solicita la acci´n es el recepcionista, una ı o vez realizada esta comprobaci´n, si el usuario es el recepcionista entonces se le permite o realizar la operaci´n, y si no lo es se le env´ a la p´gina principal. o ıa a 6.3.3. Acciones Una vez que la petici´n ha pasado los filtros y estos han decidido qu´ acci´n realizar, o e o entonces el ActionServlet de Struts debe llamar a la acci´n a la cual corresponda realizar o la operaci´n solicitada. En el fichero de configuraci´n de struts, struts-config.xml, es donde o o se encuentran definidas las URLs y la acci´n que se debe ejecutar cuando se solicita dicha o URL. Adem´s de la acci´n que se tiene que ejecutar, en este fichero tambi´n se pueden definir a o e propiedades, para que luego puedan ser utilizadas por ejemplo por los filtros, y redirecciones con nombre, de forma que cuando una acci´n se ejecute pueda usar esos nombres o para redirigir la acci´n a una p´gina u otra acci´n. Por otro lado, se indican, de la misma o a o forma, los ActionForm correspondientes a los formularios que debe manejar y procesar cada acci´n. o En este caso, para una mejor comprensi´n del sistema, las acciones se han dividido o en paquetes seg´n lo que manejan, o para que se utilizan dichas acciones, como se pueu de observar en la figura 6.6. Por ejemplo, hay paquetes donde est´n todas las acciones a relacionadas con las reservas u otro donde est´n las que tienen relaci´n con las ofertas, a o etc.
    • 6.3. Capa del Controlador 99 Adem´s para facilitar el manejo de diversas operaciones que pueden tomar mas de una a acci´n para realizarse, se vio la nececidad de crear unas clases de apoyo a las que se le dio o el nombre de XXXManager. http.controller actions clients misc offers payment reservations rooms users frontcontroller offers reservations rooms session Figura 6.6: Paquetes - Distribucion de Acciones de Struts A continuaci´n se muestra en la figura 6.7 el diagrama de c´mo se organiza realmente o o el patr´n Front Controller junto con el de Chain of Responsability en el desarrollo final o de este proyecto. 6.3.4. Clases de Utilidad y Soporte a Acciones Para dar soporte a la estructura del patr´n Front Controller se definen clases abstractas o que tienen que ser luego extendidas por las acciones y los formularios, pero adem´s de poder a agrupar las acciones todas bajo una misma clase padre, esta clase abstracta tambi´n sirve e para realizar operaciones comunes a todas las acciones, como el procesamiento de algunas excepciones, etc.
    • 6.3. Capa del Controlador 100 org::apache::struts::tiles::TilesRequestProcessor http::controller::frontcontroller::PreProcessingFilter http::controller::frontcontroller::HotelPortalRequestProcessor -nextFilter : PreProcessingFilter ~firstPreProcessingFilter : PreProcessingFilter <<create>> +HotelPortalRequestProcessor() #processActionPerform(... : ...) : ActionForward <<create>> <<create>> +PreProcessingFilter(nextFilter : PreProcessingFilter) +process(... : ...) : ActionForward #doProcess(... : ...) : ActionForward #doOnInternalErrorException(... : ...) : ActionForward 1 <<call>> http::controller::frontcontroller::SessionPreProcessingFilter 0..* org::apache::struts::action::ActionForm org::apache::struts::action::Action <<create>> +SessionPreProcessingFilter(... : ...) #doProcess(... : ...) : ActionForward http::controller::frontcontroller::AuthenticationPreProcessingFilter http::util::struts::action::DefaultActionForm http::util::struts::action::DefaultAction +execute(... : ...) : ActionForward -serialVersionUID : long <<create>> +AuthenticationPreProcessingFilter(... : ...) #doProcess(... : ...) : ActionForward #doExecute(... : ...) #getLocale(request : HttpServletRequest) : Locale #doOnInternalErrorException(... : ...) http::controller::frontcontroller::AdminOnlyPreProcessingFilter http::view::actionforms::FindClientsForm <<create>> +AdminOnlyPreProcessingFilter(... : ...) #doProcess(... : ...) : ActionForward http::view::actionforms::FindIncidentsForm Todas las acciones que extienden esta clase se encuentran en los paquetes http.controller.actions.clients, misc, offers, payment, reservations, rooms y users. http::view::actionforms::FindOffersForm http::view::actionforms::FindReservationsForm http::view::actionforms::FindRoomsForm Pero no se incluyen aquí porque son una gran cantidad, además todas estas acciones hacen uso de los actionForms que se incluyeron en este diagrama http::controller::frontcontroller::ReceptionistOnlyPreProcessingFilter <<create>> +ReceptionistOnlyPreProcessingFilter(... : ...) #doProcess(... : ...) : ActionForward http::view::actionforms::IncidentForm http::view::actionforms::LoginForm http::view::actionforms::OfferForm http::view::actionforms::RoomReservationForm http::view::actionforms::RoomForm http::view::actionforms::OfferTypeForm http::view::actionforms::RoomTypeForm http::view::actionforms::UserProfileForm Figura 6.7: Diagrama Aplicaci´n de Front Controller o Las clases de utilidad que se han definido son: DefaultAction, de la cual derivan luego todas las acciones, y DefaultFormAction que extienden luego todos los formularios. Estas clases se pueden ver claramente en el diagrama de la figura 6.7 que se acaba de mostrar. Para dar soporte a algunas acciones, no basta con los m´todos que proporcionan las e fachadas del modelo, sino que hacen falta algunas clases de soporte que ayuden a procesar algunas operaciones. Esta necesidad se hace visible cuando aparece la necesidad de mantener alguna informaci´n en cach´ a la espera de algunos otros datos para luego poder o e enviar todo junto al m´todo correspondiente de la fachada del modelo. Estas clases de e soporte son las siguientes:
    • 6.3. Capa del Controlador SessionManager 101 Esta clase proporciona diferentes m´todos que ayudan a gestionar las e sesiones de los clientes, de esta forma si por ejemplo un cliente se autentica en el sistema o modifica sus datos personales, esta clase mantiene actualizada su sesi´n y si es necesario o tambi´n actualiza las cookies de su navegador. Adem´s en ocasiones ser´ util por ejemplo e a a´ cuando se trata del recepcionista, el cual tiene que poder realizar acciones en nombre del cliente que se lo solicita, en estos casos la clase SessionManager mantendr´ en todo a momento qui´n es el usuario real del sistema (el recepcionista) y qui´n es el usuario efectivo e e (el cliente). Esta clase ser´ en la que se apoyen los filtros de procesamiento a la hora de comprobar a si un usuario est´ autenticado, si es el administrador o si es el recepcionista. a ReservationsManager La forma en la que se procesan las reservas hacen obligatorio el guardar algunos datos a la espera de la confirmaci´n, de que se desea hacer, que estos o sean persistentes, en cuyo caso hay que pasar todos los datos a la fachada de gesti´n de o reservas o a la de gesti´n de reservas web para que estas se encarguen de su procesamiento o final. Por ejemplo, cuando se realiza una nueva reserva, se le va preguntando al cliente que introduzca los datos para reservar una habitaci´n, lo que se llama l´ o ınea de reserva en la aplicaci´n, y una reserva contiene una o varias de estas l´ o ıneas, por lo que se ir´ preguntando a al cliente de hacer m´s l´ a ıneas de reserva o si desea guardarlas. Al terminar se le pasan a la fachada correspondiente todas las l´ ıneas para que cree la nueva reserva. El proceso de modificaci´n de una reserva es algo parecido, al cliente se le permite borrar las l´ o ıneas de reserva que quiera y a˜adir otras nuevas, al terminar el cliente debe elegir si desea guardar n los cambios o no, en caso afirmativo todos los cambios se guardan juntos llamando a la acci´n correspondiente de la fachada y ahorrando as´ m´ltiples accesos a la base de datos. o ı u OffersManager En el caso de las ofertas, cuando se crea una nueva oferta o se modifica no hace falta realizarlo en varios pasos, pero s´ hay que dar la opci´n de que cuando se ı o
    • 6.4. Arquitectura del Modelo 102 desea crear una oferta se pueda crear en ese instante un nuevo tipo de oferta. La creaci´n o de este nuevo tipo de oferta la hay que mantener en la cach´ a la espera de la confirmaci´n e o de que se quiere crear la oferta, en caso afirmativo se crear´n simult´neamente el nuevo a a tipo y la nueva oferta, pasando todos los datos conjuntamente a la fachada del modelo. RoomsManager As´ como con las ofertas, cuando se crea una nueva habitaci´n o se ı o modifican sus datos no hace falta realizarlo en varios pasos, pero s´ hay que dar la opci´n ı o de que cuando se desea crear una habitaci´n se pueda crear en ese instante un nuevo o tipo de habitaci´n. La creaci´n de este nuevo tipo la hay que mantener en la cach´ a o o e la espera de la confirmaci´n de que se quiere crear la habitaci´n, en caso afirmativo se o o crear´n simult´neamente el nuevo tipo y la nueva habitaci´n, pasando todos los datos a a o conjuntamente a la fachada del modelo. 6.4. Arquitectura del Modelo Como ya se ha mencionado, el modelo es la parte de la aplicaci´n que implementa la o l´gica de negocio, es decir, es donde se decide c´mo se llevar´n a cabo todos los casos de o o a uso estudiados con anterioriad, que el sistema debe realizar. Se comienza construyendo la base de datos, para que esta est´ constru´ correctamente e ıda antes se dise˜a la misma en base a diagramas, donde se incluyen las relaciones que hay n entre las entidades que formar´n la base de datos. Luego atendiendo a una serie de reglas a preestablecidas, todas estas entidades y relaciones se pasan a un esquema denominado modelo relacional, en el cual se pueden ver con claridad las distintas tablas que habr´ que a crear en la base de datos relacional. Para desarrollar con mayor facilidad este proyecto, se ha dividido la aplicaci´n en difeo rentes subsistemas, cada uno de ellos se encarga de un subconjunto de los casos de uso. Se pretende que todos estos subsistemas sean lo m´s independientes posible unos de otros, a y adem´s se implementar´n de forma que se pueda cambiar f´cilmente la base de datos a a a
    • 6.4. Arquitectura del Modelo 103 sobre la que se guarda la informaci´n, gracias al patr´n DAO usado para acceder a los o o datos. Para acceder a los distindos subsistemas, estos ofrecen una fachada con los m´todos que e ofrecen, lo que permite cambiar la implentaci´n de dichos m´todos cuando se desee sin o e alterar las capas superiores de la aplicaci´n. o La arquitectura de los distintos sistemas es la misma para todos, de forma que en primer lugar se har´ una explicaci´n de los distintos patrones y arquitecturas usados, y a o a continuaci´n se detallar´n los diferentes subsistemas para comprobar como se utilizan o a estos patrones.
    • 6.4. Arquitectura del Modelo 6.4.1. 104 Persistencia de los Datos En este apartado se ver´ como se consigue desarrollar la base de datos en la que se a guardar´n todos los datos de la aplicaci´n, a partir de las especificaciones iniciales. a o En realidad este proyecto necesitar´ dos bases de datos distintas, una para guardar a los a usuarios, las habitaciones, las reservas y las facturas, y otra para guardar todo lo relacionado con las ofertas. Gracias a esta separaci´n, si se desea modificar el esquema de gesti´n o o de ofertas, solo se modificar´ una parte del sistema, que es totalmente independiente del a resto de la aplicaci´n. o A continuaci´n se detallar´ el proceso seguido para el dise˜o de cada una de las bases o a n de datos. 6.4.1.1. Base de Datos General En esta base de datos se necesitar´ guardar a los distintos usuarios del sistema, estos a usuarios se identificar´n mediante el DNI o el n´mero de Pasaporte, y de ellos se almaa u cenar´n los siguientes datos: nombre, apellidos, fecha de nacimiento, direcci´n, pa´ dos a o ıs, n´meros de tel´fono y la direcci´n de correo electr´nico. Adem´s se guardar´n tambi´n el u e o o a a e nombre de usuario dentro del sistema y su contrase˜a cifrada, por otro lado, de un usuario n se tendr´ que poder saber si ya es cliente del hotel y si ha confirmado su identidad. a Por otro lado tambi´n se necesitan registrar las habitaciones que hay en el hotel, estas e se identificar´n por su n´mero, y de ellas se mantendr´n almacenados el piso en el que a u a se encuentra y el posible precio extra que pueda tener. Cada habitaci´n ser´ de un solo o a tipo, aunque en el futuro puede que se necesite que pueda ser de varios tipos distintos, donde cada tipo se identifica por un n´mero generado y es el que define el precio base u de la habitaci´n, adem´s se deben de almacenar la descripci´n del tipo y el n´mero de o a o u personas para las que se destina.
    • 6.4. Arquitectura del Modelo 105 Como en una habitaci´n puede que ocurra alg´n tipo de percance, tambi´n se debe dar o u e soporte para registrar las distintas incidencias que puedan tener lugar en cada habitaci´n, o cada una de ellas se identificar´ por el n´mero de habitaci´n y por un identificador secuna u o dario generado din´micamente, de cada incidencia habr´ que mantener constancia de la a a descripci´n de la misma, el tipo (si es grave, leve, etc) y la fecha en la que se registra. o Para terminar, y como el cometido principal de la aplicaci´n es poder realizar reservas o de habitaciones, hay que dar soporte a esta opci´n. Las reservas se identificar´n por un o a c´digo de reserva y podr´n ser temporales o no, adem´s habr´ que registrar la fecha en o a a a la que se realiza. Luego una reserva podr´ contener una o varias l´ a ıneas de reserva cada cual con relaci´n a una habitaci´n, por lo que estas l´ o o ıneas se identificar´n mediante el a n´mero de habitaci´n para la que se destinan y la fecha de llegada que se debe almacenar u o en cada una, tambi´n se guardar´n la fecha de salida, el total parcial que cuesta esa e a estancia y el descuento ofrecido al aplicar las ofertas correspondientes. El total parcial se almacena porque adem´s de las reservas, las l´ a ıneas de reserva tambi´n est´n presentes e a en las facturas, por lo que una factura podr´ estar formada de igual forma por una o a varias l´ ıneas de reserva. La factura se asociar´ a una persona, que ser´ quien debe pagarla a a y se identificar´ por un n´mero de factura generado. En las facturas debe constar si ya a u est´ pagada, si a´n est´ como borrador, la fecha en la que se realiza el pago, el total que a u a forma la factura, el total parcial antes de aplicar las ofertas y las ofertas aplicadas. El dise˜o se debe realizar para que si en un futuro se necesita, se pueda a˜adir por n n ejemplo servicios extra, etc, y que estos puedan incluirse en la misma factura. Despu´s de definir todo lo que se necesita almacenar, se procede a realizar el modelo e Entidad-Relaci´n, que es un diagrama mediante el cual se muestran los requisitos expreo sados en los p´rrafos anteriores de forma g´fica a trav´s de entidades, que son las ’cosas’ a a e u ’objetos’ en el mundo real que se distinguen de todos los dem´s objetos, y relaciones, a las encargadas de mostrar como est´n ligadas las distintas entidades unas con otras. Cada a entidad tendr´ una serie de propiedades espec´ a ıficas que la describen, a estas se les llama ’atributos’ y si se puede diferenciar un´ ıvocamente una instancia de una entidad de otra de
    • 6.4. Arquitectura del Modelo 106 la misma entidad a trav´s de uno o varios de los atributos, estos forman la denominada e ’clave primaria’. En la p´gina siguiente en la figura 6.8 se puede ver como queda el dise˜o a n de esta base de datos a trav´s de un diagrama Entidad-Relaci´n. e o
    • 6.4. Arquitectura del Modelo 107 Figura 6.8: Diagrama Entidad Relaci´n - General o
    • 6.4. Arquitectura del Modelo 108 Una vez visto el dise˜o de la base de datos se procede a realizar el Modelo Relacional n de esta. El modelo relacional es un modelo de datos es una colecci´n de herramientas o conceptuales para describir los datos, sus relaciones y restricciones, para esto el modelo relacional cuenta con: una estructura para almacenar los datos y unas restricciones. La estructura b´sica y unica para el almacenamiento de los datos es la ’relaci´n’. As´ la base a ´ o ı, de datos se representa como una colecci´n de relaciones. o El modelo relacional de esta primera base de datos se puede ver representado en la figura 6.9 Figura 6.9: Modelo Relacional - General
    • 6.4. Arquitectura del Modelo 109 Cuando se tiene el modelo relacional ya se pueden diferenciar las tablas que habr´ que a crear en la base de datos con sus claves primarias identificadas y tambi´n las claves e for´neas. a Para este proyecto se usar´ como base de datos MySQL, por defecto el motor de esta a base de datos es MyISAM. Este motor es r´pido y eficiente. En un principio se pens´ en a o utilizarlo, pero viendo que para realizar la persistencia de los datos de la aplicaci´n se o necesitan realizar transacciones, se opt´ por elegir un motor de base de datos que las o soportara. El motor elegido fue InnoDB que adem´s de dar soporte para las transacciones a tambi´n soporta claves for´neas. e a Finalmente y gracias al modelo relacional realizado ya se podr´ implementar la base de a datos, esta implementaci´n se muestra en el cap´ o ıtulo 7 en la secci´n 7.2.1. o 6.4.1.2. Base de Datos de Ofertas Esta base de datos se crea con motivo de dar soporte al que ser´ el sistema que gestione a las ofertas y sus combinaciones. Para que este sistema funcione correcta y eficientemente es necesario que el dise˜o de la base de datos sea lo m´s flexible posible y que cumpla n a todos los requisitos del sistema. Este sistema debe permitir definir ofertas de distintos tipos ya que de cada tipo, luego, s´lo se podr´ aplicar una de ellas. Pero esto no es todo, adem´s se podr´n definir o a a a incompatibilidades entre ofertas, as´ luego unicamente se aplicar´n aquellas ofertas que ı ´ a sean todas compatibles entre s´ Y por otro lado habr´ que indicar a qu´ tipo de ventas ı. a e se podr´ aplicar la oferta (reservas, servicios extra, etc) y tambi´n se tendr´ que poder a e a definir una regla por la cual se restrinja a qui´n se le puede aplicar la oferta y a qui´n no. e e Las ofertas se identificar´n por un n´mero generado en el momento en la que se crean. a u Cada oferta deber´ mantener los siguientes datos: Descripci´n de la oferta, descuento que a o se ofrece con esa oferta, la fecha a partir de la cual la oferta se comienza a aplicar y cu´ndo a se termina de hacerlo, indicar si es un borrador y si est´ desactivada. Adem´s almacenar´ la a a a
    • 6.4. Arquitectura del Modelo 110 regla que se debe de cumplir para que se pueda aplicar, esta estar´ escrita en un lenguaje a de reglas que se definir´ posteriormente. Adem´s cada oferta tendr´ un tipo de oferta, a a a estos tipos deber´n guardar una descripci´n y un nombre, y se identificar´n mediante un a o a n´mero generado autom´ticamente. Luego estas ofertas podr´n ser incompatibles entre s´ u a a ı. Cada oferta a su vez podr´ ser aplicada a una serie de productos, estas aplicaciones a se resolver´n mediante un nombre del tipo de producto al que se aplicar´n y la cantidad a a m´ ınima necesaria para que se aplique. En la figura 6.10 se puede ver como queda el dise˜o n de esta base de datos a trav´s de un diagrama Entidad-Relaci´n. e o Figura 6.10: Diagrama Entidad Relaci´n - Ofertas o
    • 6.4. Arquitectura del Modelo 111 Una vez terminado el dise˜o de esta segunda base de datos se pasa a realizar el modelo n relacional, que se puede ver en la figura 6.11. Figura 6.11: Modelo Relacional - Ofertas A partir del Modelo Relacional de la figura 6.11 y optimizando las tuplas generadas por este, ya se podr´n crear las tablas en la base de datos. La implementaci´n real de esta a o base de datos se ver´ de forma m´s detallada en el cap´ a a ıtulo 7 en la secci´n 7.2.2. o 6.4.2. 6.4.2.1. Patrones Utilizados en el Modelo Value Object (VO) Este patr´n se utiliza cuando se necesita representar un conjunto de atributos proceo dentes de uno o varios objetos del dominio, adem´s, normalmente, representa en forma a de objeto del dominio a una entidad completa representada en la base de datos. Por esto ultimo el patr´n VO se utiliza conjuntamente con el patr´n DAO que se explicar´ en la ´ o o a siguiente secci´n y que es el encargado de acceder a la base de datos y hacer persistentes o los atributos de los VO.
    • 6.4. Arquitectura del Modelo 112 En la figura 6.12 se muestra la estructura b´sica de este patr´n. a o <<interface>> java.io.Serializable <<realize>> VO <<interface>> DAO -atributos : ... <<call>> +metodos get/set() Figura 6.12: Diagrama de Value Object La clase VO de la figura es la que representa el objeto y ofrece m´todos de lectura y e escritura para sus atributos. Este objeto debe implementar la interfaz Serializable ya que esta, aunque simplemente es una interfaz marcadora, luego este objeto se podr´ transmitir a por red y reconstruir con facilidad gracias a un API que proporciona Java para convertir autom´ticamente el estado de una instancia en un vector de bytes y viceversa. a Los objetos VO son utilizados tanto por los DAO para devolver valores persistentes o recoger valores para actualizar o crear, como para las fachadas del subsistema que lo necesite. En esta aplicaci´n se usar´ la notaci´n xxxVO para estos objetos o a o 6.4.2.2. Data Access Object (DAO) El patr´n DAO es el encargado de abstraer el acceso a los datos. Esta arquitectura o ofrecer´ al programador una interfaz com´n para acceder a la informaci´n, sin importar a u o ni c´mo ni d´nde est´n almacenados los datos. Adem´s, as´ se da la posibilidad de cambiar o o a a ı la implementaci´n de acceso a la informaci´n cuando se desee. Para posibilitar este cambio, o o se usa el patr´n Factory (Factor´ que consta de una clase encargada de devolver un objeto o ıa) del tipo solicitado. Para crear el nuevo objeto esta clase debe de saber el nombre de la clase del mismo, y para ello se ayuda de una utilidad que es ConfigurationParametersManager,
    • 6.4. Arquitectura del Modelo 113 una clase que a partir de una cadena devuelve el nombre de recurso deseado despu´s de e leerlo en un fichero de configuraci´n. o En la siguiente figura (6.13) se muestra c´mo se estructuran las clases que dan forma o a este patr´n, y donde se incluye tambi´n el patr´n VO para que se vea claramente la o e o relaci´n de uno con otro. o DAOFactory ConfigurationParametersManager -daoClass : Class <<call>> -DAOFactory() +getDAO() : DAO <<instantiate>> DAO VO -atributos : ... +create(c : Connection,vo : VO) : VO +exists(c : Connection,id : Integer) : boolean +find(c : Connection,id : Integer) : VO +findBy(c : Connection,id : Integer,start : Integer,count : Integer) : List +update(c : Connection,vo : VO) +remove(c : Connection,id : Integer) <<call>> +metodos get/set() Figura 6.13: Diagrama de Data Access Object Pero esta estructura a´n se puede mejorar, como en este caso el volumen de datos no u ser´ peque˜o, la informaci´n se almacenar´ en una base de datos relacional. Te´ricamente a n o a o todas las bases de datos relacionales comprenden correctamente el lenguaje de consultas SQL, pero en la pr´ctica esto no es as´ aunque SQL es un est´ndar cada fabricante tiene a ı, a sus peque˜as variantes, lo que puede complicar un poco m´s el dise˜o, ya que las sentencias n a n SQL que se escriban para hacer consultas sobre la base de datos variar´n dependiendo de la a base de datos que se utilice. Las sencencias que sufren mayores variaciones entre fabricantes son sobre todo las de inserci´n de datos, ya que para las sentencias de consultas simples o se utiliza el mismo SQL en todas las bases de datos. Con el dise˜o anterior, si se quisiera cambiar de base de datos tendr´ n ıamos que modificar la clase DAO, aunque s´lo se tuviese que cambiar la sentencia de inserci´n. Por este o o motivo en el dise˜o utilizado se opt´ por separar la interfaz de acceso a los datos DAO n o y su implementaci´n, de forma que se pudiese tener una implementaci´n abstracta de los o o
    • 6.4. Arquitectura del Modelo 114 m´todos comunes en todas las bases de datos, y redefinir exclusivamente aquellos que fuese e necesario, y en la figura 6.14 se puede ver como se organizan estas nuevas clases. DAOFactory ConfigurationParametersManager -daoClass : Class -DAOFactory() +getDAO() : DAO <<call>> <<instantiate>> <<interface>> DAO +create(c : Connection,vo : VO) : VO +exists(c : Connection,id : Long) : boolean +find(c : Connection,id : Long) : VO +findBy(c : Connection,id : Long,start : Integer,count : Integer) : List +update(c : Connection,vo : VO) +remove(c : Connection,id : Long) VO <<realize>> -atributos : ... +metodos get/set() AbstractDAO SpecificDAO Figura 6.14: Diagrama de Data Access Object Utilizado Como se puede observar, todos los m´todos necesitan recibir la conexi´n, esto se hace e o para poder agrupar luego varias operaciones en una transacci´n cuando sea necesario. La o clase DAO define una interfaz para insertar, borrar, buscar y actualizar objetos VO. Este es un ejemplo de la aplicaci´n de otro patr´n simple, el Adapter (Adaptador), d´nde o o o DAOFactory permite obeter una instancia del adaptador que proceda para la aplicaci´n. o Gracias a este dise˜o, como ya se ha mencionado, es posible hacer ’plug-n-play’ de adapn tadores sin tener que recompilar la aplicaci´n cuando se cambia de base de datos. En el o desarrollo del sistema se usar´ la notaci´n xxxDAO, xxx representar´ el nombre de la a o a entidad de la base de datos que corresponde al DAO en cuesti´n. o
    • 6.4. Arquitectura del Modelo 6.4.2.3. 115 Session Facade y Business Delegate Estos dos patrones forman una capa del modelo que utiliza los DAOs para acceder a los datos y ofrece unos m´todos a las capas superiores, vista y controlador. Estas arquitecturas e se utilizan fundamentalmente para proporcionar una capa m´s sencilla que de soporte para a implementar los casos de uso definidos, ocultando a su vez la tecnolog´ utilizada. ıa El patr´n Session Facade es una aplicaci´n del patr´n Facade (Fachada) gracias al cual el o o o subsistema desarrollado resulta m´s f´cil de utilizar por parte de capas superiores y reduce a a el acoplamiento, de forma que la modificaci´n del subsistema no afecta a las otras capas o que lo utilicen. En este caso el Session Facade representa control y flujo, no persistencia, de la cual ya se encargan los DAOs, adem´s una Session Facade representa un conjunto de a casos de uso relacionados entre s´ y cada uno de estos conjuntos formar´n un subsistema ı, a de la aplicaci´n. En este caso se desarrollar´n los siguientes Session Facades para impleo a mentar todos los subsistemas: ClientesFacade, FacturasWebFacade, HabitacionesFacade, ReservasWebFacade, UsuariosWebFacade, OfertaFacade y TipoOfertaFacade. Conjuntamente con el Session Facade se utiliza el patr´n Business Delegate, este sirve o para ocultar las tecnolog´ utilizadas en el modelo, normalemente un objeto Business ıas Delegate oculta a un Session Facade, pero en este caso ser´n el mismo, y aunque no a ser´ necesario dar la opci´n de cambiar la tecnolog´ usada, por ejemplo utilizar EJB, si a o ıa en el futuro se desea hacer este cambio se har´ de forma sencilla. Como en el sistema s´lo a o habr´ un Business Delegate por subsistema se denotar´ por GeneralXxxFacade. a a Para dar soporte a las consultas a la base de datos, hay que recordar que los DAO necesitaban que se les proveera de una conexi´n para ejecutar las consultas, se tiene una o clase de utilidad, en este caso SimpleDataSource, que valdr´ para crear una conexi´n nueva a o a la base de datos y devolverla. Tambi´n hay que dar soluci´n a unos problemas. El primero que se encuentra es que e o un Session Facade puede tener m´s de 10 operaciones, lo que desembocar´ en una clase a ıa muy grande. Para solucionar este primer contratiempo se har´ que cada operaci´n se a o
    • 6.4. Arquitectura del Modelo 116 implemente en una clase, se denominar´n clases Action, con esto lo que se consigue es que el a Session Facade delegue la implementaci´n de cada operaci´n en la Action correspondiente. o o La organizaci´n de las distintas clases de este conjunto de patrones se puede ver en la figura o 6.15 <<interface>> XxxFacade Actions <<realize>> GeneralXxxFacade <<call>> -dataSource : DataSource PlainActionProcessor +GeneralXxxFacade() <<call>> <<call>> SimpleDataSource +getConnection() : Connection Figura 6.15: Diagrama de Session Facade y Business Delegate Como segundo problema est´ la transaccionalidad necesaria en muchas de las acciones a aunque otras no lo necesiten. Las acciones transaccionales deber´n solicitar una conexi´n a o al inicio de la operaci´n y cerrarla al terminar. La resoluci´n de este ultimo problema se o o ´ logra utilizando el procesador de acciones, en este caso PlainActionProcessor, lo unico que ´ hay que conseguir es que teniendo dos m´todos, uno para procesar las acciones transace cionales y otro para procesar las que no lo son, las acciones transaccionales las procese autom´ticamente el m´todo que corresponde y lo mismo para las no transaccionales. a e El procesador de acciones que se ve en la figura 6.15 necesita que las acciones implementen una interfaz PlainAction, para desta forma identificarlas y poder llamar a su m´todo e execute(). Esta opci´n, es la que se aprovecha para diferenciar las acciones transaccionao les, se crean dos nuevas interfaces que heredan de PlainAction: TransactionalPlainAction y NonTransactionalPlainAction. As´ las acciones que implementen cualquiera de estas dos ı nuevas interfaces estar´n implementando tambi´n la interfaz PlainAction, como bien se a e puede ver en la figura 6.16. Las interfaces que se crean se denominan Markers (Marcado-
    • 6.4. Arquitectura del Modelo 117 res) ya que no tienen la firma de ning´n m´todo y simplemente sirven para diferenciar u e unas clases de otras, en este caso las que implementan una transacci´n y las que no. o PlainActionProcessor -PlainActionProcessor() +process(dataSource : DataSource,action : NonTransactionalPlainAction) : Object +process(dataSource : DataSource,action : TransactionalPlainAction) : Object <<call>> <<interface>> PlainAction +execute(c : Connection) : Object <<interface>> NonTransactionalPlainAction <<interface>> TransactionalPlainAction Figura 6.16: Diagrama del Procesador de Acciones 6.4.3. Capa de Acceso a la Base de Datos Para acceder a la informaci´n guardada en la base de datos y modificarla si fuera necesao rio, Java proporciona un API JDBC para realizarlo. Adem´s en este proyecto se utilizar´ el a a patr´n DAO explicado en la secci´n 6.4.2.2. Para simplificar el trabajo, se construir´ un o o a objeto DAO por cada entidad y relaci´n de la base de datos, esto es, un DAO por cada o tabla de la base de datos. Los objetos DAO tendr´n m´todos de creaci´n de nuevos valores a e o en la base de datos, eliminaci´n, modificaci´n y consulta de datos seg´n algunos par´meo o u a tros que se proporcionen. Aunque se implementar´n todos los m´todos que se puedan a e necesitar, luego no se usar´n todos, pero los objetos DAO ya quedar´ preparados por si a ıan en el futuro se necesitasen realizar otras consultas. Los objetos DAO utilizan los objetos VO relacionados con ellos, por lo que tambi´n se crear´ un objeto VO por cada una de e a las tablas que hay en la base de datos. La estructura de estos paquetes se puede observar en las figuras 6.17 y 6.18
    • 6.4. Arquitectura del Modelo 118 Figura 6.17: Estructura de los paquetes DAO y VO xxx DAO SQLxxxDAOFactory <<instantiate>> <<interface>> SQLxxxDAO <<realize>> MySQLxxxDAO AbstractSQLxxxDAO VO xxxVO Figura 6.18: Diagrama General de los DAO Y a continuaci´n se muestran los diagramas de todos los DAOs de esta aplicaci´n, o o clasificados seg´n el paquete en el que se encuentran. La estructura es la misma para u todos, pero los m´todos que ofrecen no lo son. Las clases MySQLxxDAO se utilizan para e redefinir el m´todo de creaci´n de datos, ya que si luego se desea cambiar de gestor de base e o de datos, las sentencias de consulta en SQL normalmente son iguales en todos los gestores, pero las de inserci´n no, sobre todo a la hora de generar las claves. En caso de que esto o suceda, simplemente habr´ que cambiar la clase MySQLxxxDAO por la que corresponda ıa para el nuevo gestor de base de datos.
    • 6.4. Arquitectura del Modelo 6.4.3.1. 119 Paquete ’persona’ SQLPersonaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLPersonaDAOFactory() -getDAOClass() : Class +getDAO() : SQLPersonaDAO <<interface>> SQLPersonaDAO +addPersona(connection : Connection,personaVO : PersonaVO) : PersonaVO +removePersona(connection : Connection,dniPas : String) : void +existsPersona(connection : Connection,dniPas : String) : boolean +existsPersona(connection : Connection,userName : String,userPassword : String) : boolean +existsUserName(connection : Connection,userName : String) : boolean +findPersona(connection : Connection,dniPas : String) : PersonaVO +findPersona(connection : Connection,userName : String,userPassword : String) : PersonaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByPais(connection : Connection,pais : String,startIndex : int,count : int) : Collection +getByCliente(connection : Connection,cliente : boolean,startIndex : int,count : int) : Collection +getByUsuarioConf(connection : Connection,usuarioConf : boolean,startIndex : int,count : int) : Collection +GetByNameSurnameAndDniPas(connection : Connection,name : String,search1 : boolean,surname : String,search2 : boolean,dniPas : String,search3 : boolean,startIndex : int,count : int) : Collection +updateEMail(connection : Connection,dniPas : String,eMail : String) : void +updateUsuarioConf(connection : Connection,dniPas : String,usuarioConf : boolean) : void +updateNomUsuario(connection : Connection,dniPas : String,newNomUsuario : String) : void +updatePassword(connection : Connection,dniPas : String,newPassword : String) : void +updateNombre(connection : Connection,dniPas : String,newNombre : String) : void +updateApellidos(connection : Connection,dniPas : String,newApellidos : String) : void +updateDirCalle(connection : Connection,dniPas : String,newDirCalle : String) : void +updatePais(connection : Connection,dniPas : String,newPais : String) : void +updateCliente(connection : Connection,dniPas : String,cliente : boolean) : void +updateTelefono1(connection : Connection,dniPas : String,newTelefono : String) : void +updateTelefono2(connection : Connection,dniPas : String,newTelefono : String) : void <<realize>> AbstractSQLPersonaDAO +addPersona(connection : Connection,personaVO : PersonaVO) : PersonaVO +removePersona(connection : Connection,dniPas : String) : void +existsPersona(connection : Connection,dniPas : String) : boolean +existsUserName(connection : Connection,userName : String) : boolean +existsPersona(connection : Connection,userName : String,userPassword : String) : boolean +findPersona(connection : Connection,dniPas : String) : PersonaVO +findPersona(connection : Connection,userName : String,userPassword : String) : PersonaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByPais(connection : Connection,pais : String,startIndex : int,count : int) : Collection +getByCliente(connection : Connection,cliente : boolean,startIndex : int,count : int) : Collection +getByUsuarioConf(connection : Connection,usuarioConf : boolean,startIndex : int,count : int) : Collection +GetByNameSurnameAndDniPas(connection : Connection,name : String,search1 : boolean,surname : String,search2 : boolean,dniPas : String,search3 : boolean,startIndex : int,count : int) : Collection +updateEMail(connection : Connection,dniPas : String,eMail : String) : void +updateUsuarioConf(connection : Connection,dniPas : String,usuarioConf : boolean) : void +updateNomUsuario(connection : Connection,dniPas : String,newNomUsuario : String) : void +updatePassword(connection : Connection,dniPas : String,newPassword : String) : void +updateNombre(connection : Connection,dniPas : String,newNombre : String) : void +updateApellidos(connection : Connection,dniPas : String,newApellidos : String) : void +updateDirCalle(connection : Connection,dniPas : String,newDirCalle : String) : void +updatePais(connection : Connection,dniPas : String,newPais : String) : void +updateCliente(connection : Connection,dniPas : String,cliente : boolean) : void +updateTelefono1(connection : Connection,dniPas : String,newTelefono : String) : void +updateTelefono2(connection : Connection,dniPas : String,newTelefono : String) : void MySQLPersonaDAO hotel::modelo::persona::vo::PersonaVO <<call>> +addPersona(connection : Connection,personaVO : PersonaVO) : PersonaVO <<call>> -serialVersionUID : long -dniPas : String -eMail : String -usuarioConf : boolean -nomUsuario : String -password : String -nombre : String -apellidos : String -dirCalle : String -pais : String -cliente : boolean -telefono1 : String -telefono2 : String Figura 6.19: Diagrama del Paquete ’persona’
    • 6.4. Arquitectura del Modelo 6.4.3.2. 120 Paquete ’tipohabitacion’ SQLTipoHabitacionDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLTipoHabitacionDAOFactory() -getDAOClass() : Class +getDAO() : SQLTipoHabitacionDAO <<interface>> SQLTipoHabitacionDAO +addTipoHabitacion(connection : Connection,tipoHabitacionVO : TipoHabitacionVO) : TipoHabitacionVO +removeTipoHabitacion(connection : Connection,idTipo : Long) : void +existsTipoHabitacion(connection : Connection,idTipo : Long) : boolean +findTipoHabitacion(connection : Connection,idTipo : Long) : TipoHabitacionVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +updatePrecioBase(connection : Connection,idTipo : Long,newPrecioBase : double) : void +updateDescripcion(connection : Connection,idTipo : Long,newDescripcion : String) : void +updateNumPersonas(connection : Connection,idTipo : Long,newNumPersonas : Long) : void <<realize>> AbstractSQLTipoHabitacionDAO +addTipoHabitacion(connection : Connection,tipoHabitacionVO : TipoHabitacionVO) : TipoHabitacionVO +removeTipoHabitacion(connection : Connection,idTipo : Long) : void +existsTipoHabitacion(connection : Connection,idTipo : Long) : boolean +findTipoHabitacion(connection : Connection,idTipo : Long) : TipoHabitacionVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +updatePrecioBase(connection : Connection,idTipo : Long,newPrecioBase : double) : void +updateDescripcion(connection : Connection,idTipo : Long,newDescripcion : String) : void +updateNumPersonas(connection : Connection,idTipo : Long,newNumPersonas : Long) : void MySQLTipoHabitacionDAO +addTipoHabitacion(connection : Connection,tipoHabitacionVO : TipoHabitacionVO) : TipoHabitacionVO TipoHabitacionVO -serialVersionUID : long -idTipo : Long -descripcion : String -numPersonas : Long -precioBase : double Figura 6.20: Diagrama del Paquete ’tipohabitacion’
    • 6.4. Arquitectura del Modelo 6.4.3.3. 121 Paquete ’habitacion’ SQLHabitacionDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLHabitacionDAOFactory() -getDAOClass() : Class +getDAO() : SQLHabitacionDAO <<interface>> SQLHabitacionDAO +addHabitacion(connection : Connection,habitacionVO : HabitacionVO) : HabitacionVO +removeHabitacion(connection : Connection,numero : Long) : void +existsHabitacion(connection : Connection,numero : Long) : boolean +findHabitacion(connection : Connection,numero : Long) : HabitacionVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByPiso(connection : Connection,piso : Long,startIndex : int,count : int) : Collection +updatePrecioExtra(connection : Connection,numero : Long,newPrecioExtra : double) : void +updatePiso(connection : Connection,numero : Long,newPiso : double) : void <<realize>> AbstractSQLHabitacionDAO +addHabitacion(connection : Connection,habitacionVO : HabitacionVO) : HabitacionVO +existsHabitacion(connection : Connection,numero : Long) : boolean +findHabitacion(connection : Connection,numero : Long) : HabitacionVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByPiso(connection : Connection,piso : Long,startIndex : int,count : int) : Collection +removeHabitacion(connection : Connection,numero : Long) : void +updatePrecioExtra(connection : Connection,numero : Long,newPrecioExtra : double) : void +updatePiso(connection : Connection,numero : Long,newPiso : double) : void MySQLHabitacionDAO +addHabitacion(connection : Connection,habitacionVO : HabitacionVO) : HabitacionVO HabitacionVO -serialVersionUID : long -numero : Long -piso : Long -precioExtra : Double Figura 6.21: Diagrama del Paquete ’habitacion’
    • 6.4. Arquitectura del Modelo 6.4.3.4. 122 Paquete ’esdetipo’ SQLEsDeTipoDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLEsDeTipoDAOFactory() -getDAOClass() : Class +getDAO() : SQLEsDeTipoDAO <<interface>> SQLEsDeTipoDAO +addEsDeTipo(connection : Connection,esDeTipoVO : EsDeTipoVO) : EsDeTipoVO +removeEsDeTipo(connection : Connection,numero : Long,idTipo : Long) : void +removeEsDeTipoByNumber(connection : Connection,numero : Long) : void +existsEsDeTipo(connection : Connection,numero : Long,idTipo : Long) : boolean +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByTipo(connection : Connection,idTipo : Long,startIndex : int,count : int) : Collection +getByHabitacion(connection : Connection,numero : Long,startIndex : int,count : int) : Collection <<realize>> AbstractSQLEsDeTipoDAO +addEsDeTipo(connection : Connection,esDeTipoVO : EsDeTipoVO) : EsDeTipoVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +existsEsDeTipo(connection : Connection,numero : Long,idTipo : Long) : boolean +getByHabitacion(connection : Connection,numero : Long,startIndex : int,count : int) : Collection +getByTipo(connection : Connection,idTipo : Long,startIndex : int,count : int) : Collection +removeEsDeTipo(connection : Connection,numero : Long,idTipo : Long) : void +removeEsDeTipoByNumber(connection : Connection,numero : Long) : void MySQLEsDeTipoDAO +addEsDeTipo(connection : Connection,esDeTipoVO : EsDeTipoVO) : EsDeTipoVO EsDeTipoVO -serialVersionUID : long -numero : Long -idTipo : Long Figura 6.22: Diagrama del Paquete ’esdetipo’
    • 6.4. Arquitectura del Modelo 6.4.3.5. 123 Paquete ’incidencia’ SQLIncidenciaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLIncidenciaDAOFactory() -getDAOClass() : Class +getDAO() : SQLIncidenciaDAO <<interface>> SQLIncidenciaDAO +addIncidencia(connection : Connection,incidenciaVO : IncidenciaVO) : IncidenciaVO +removeIncidencia(connection : Connection,numero : Long,idSecundario : Long) : void +existsIncidencia(connection : Connection,numero : Long,idSecundario : Long) : boolean +findIncidencia(connection : Connection,numero : Long,idSecundario : Long) : IncidenciaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByHabitacion(connection : Connection,numero : Long,startIndex : int,count : int) : Collection +getByTipo(connection : Connection,tipo : String,startIndex : int,count : int) : Collection <<realize>> AbstractSQLIncidenciaDAO +addIncidencia(connection : Connection,incidenciaVO : IncidenciaVO) : IncidenciaVO +existsIncidencia(connection : Connection,numero : Long,idSecundario : Long) : boolean +findIncidencia(connection : Connection,numero : Long,idSecundario : Long) : IncidenciaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByHabitacion(connection : Connection,numero : Long,startIndex : int,count : int) : Collection +getByTipo(connection : Connection,tipo : String,startIndex : int,count : int) : Collection +removeIncidencia(connection : Connection,numero : Long,idSecundario : Long) : void MySQLIncidenciaDAO +addIncidencia(connection : Connection,incidenciaVO : IncidenciaVO) : IncidenciaVO IncidenciaVO -serialVersionUID : long -numero : Long -idSecundario : Long -tipo : String -descripcion : String -fechaRegistro : Calendar Figura 6.23: Diagrama del Paquete ’incidencia’
    • 6.4. Arquitectura del Modelo 6.4.3.6. 124 Paquete ’lineadereserva’ SQLLineaDeReservaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLLineaDeReservaDAOFactory() -getDAOClass() : Class +getDAO() : SQLLineaDeReservaDAO <<interface>> SQLLineaDeReservaDAO +addLineaDeReserva(connection : Connection,lineaDeReservaVO : LineaDeReservaVO) : LineaDeReservaVO +removeLineaDeReserva(connection : Connection,numero : Long,fechaInicio : Calendar) : void +existsReservaForHabitacionForDay(connection : Connection,numero : Long,fecha : Calendar) : boolean +findLineaDeReserva(connection : Connection,codigoReserva : Long,numero : Long,fechaInicio : Calendar) : LineaDeReservaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByCodigoReserva(connection : Connection,codigoReserva : Long,startIndex : int,count : int) : Collection +getByCodigoReservaAndHabitacion(connection : Connection,codigoReserva : Long,numero : Long,startIndex : int,count : int) : Collection +getByCodigoReservaAndPendientes(connection : Connection,codigoReserva : Long,startIndex : int,count : int) : Collection +getByFactura(connection : Connection,numeroFactura : Long,startIndex : int,count : int) : Collection +getByCancelada(connection : Connection,cancelada : boolean,startIndex : int,count : int) : Collection +getByHabitacionAndActual(connection : Connection,numero : Long,startIndex : int,count : int) : Collection +updateReservaCancelada(connection : Connection,codigoReserva : Long,cancelada : boolean) : void +updateLineaReservaCancelada(connection : Connection,numero : Long,fechaInicio : Calendar,cancelada : boolean) : void +updateTotalParcial(connection : Connection,lineaDeReservaVO : LineaDeReservaVO,totalParcial : double) : void +updateDescuento(connection : Connection,lineaDeReservaVO : LineaDeReservaVO,descuento : double) : void <<realize>> AbstractSQLLineaDeReservaDAO +addLineaDeReserva(connection : Connection,lineaDeReservaVO : LineaDeReservaVO) : LineaDeReservaVO +removeLineaDeReserva(connection : Connection,numero : Long,fechaInicio : Calendar) : void +existsReservaForHabitacionForDay(connection : Connection,numero : Long,fecha : Calendar) : boolean +findLineaDeReserva(connection : Connection,codigoReserva : Long,numero : Long,fecha : Calendar) : LineaDeReservaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByCancelada(connection : Connection,cancelada : boolean,startIndex : int,count : int) : Collection +getByCodigoReserva(connection : Connection,codigoReserva : Long,startIndex : int,count : int) : Collection +getByCodigoReservaAndPendientes(connection : Connection,codigoReserva : Long,startIndex : int,count : int) : Collection +getByCodigoReservaAndHabitacion(connection : Connection,codigoReserva : Long,numero : Long,startIndex : int,count : int) : Collection +getByFactura(connection : Connection,numeroFactura : Long,startIndex : int,count : int) : Collection +getByHabitacionAndActual(connection : Connection,numero : Long,startIndex : int,count : int) : Collection +updateLineaReservaCancelada(connection : Connection,numero : Long,fechaInicio : Calendar,cancelada : boolean) : void +updateReservaCancelada(connection : Connection,codigoReserva : Long,cancelada : boolean) : void +updateTotalParcial(connection : Connection,lineaDeReservaVO : LineaDeReservaVO,totalParcial : double) : void +updateDescuento(connection : Connection,lineaDeReservaVO : LineaDeReservaVO,descuento : double) : void MySQLLineaDeReservaDAO +addLineaDeReserva(connection : Connection,lineaDeReservaVO : LineaDeReservaVO) : LineaDeReservaVO LineaDeReservaVO -serialVersionUID : long -codigoReserva : Long -numero : Long -fechaInicio : Calendar -fechaFin : Calendar -descuento : double -totalParcial : double -numeroFactura : Long -cancelada : boolean Figura 6.24: Diagrama del Paquete ’lineadereserva’
    • 6.4. Arquitectura del Modelo 6.4.3.7. 125 Paquete ’reserva’ SQLReservaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLReservaDAOFactory() -getDAOClass() : Class +getDAO() : SQLReservaDAO <<interface>> SQLReservaDAO +addReserva(connection : Connection,reservaVO : ReservaVO) : ReservaVO +removeReserva(connection : Connection,codigo : Long) : void +existsReserva(connection : Connection,codigo : Long) : boolean +findReserva(connection : Connection,codigo : Long) : ReservaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getEntreFechas(connection : Connection,fecha1 : Calendar,fecha2 : Calendar,startIndex : int,count : int) : Collection +getByPersona(connection : Connection,dniPas : String,startIndex : int,count : int) : Collection +getByTemporal(connection : Connection,temporal : boolean,startIndex : int,count : int) : Collection +updateTemporal(connection : Connection,codigo : Long,temporal : boolean) : void +updateFechaRealizacion(connection : Connection,codigo : Long,fechaRealizacion : Calendar) : void <<realize>> AbstractSQLReservaDAO +addReserva(connection : Connection,reservaVO : ReservaVO) : ReservaVO +removeReserva(connection : Connection,codigo : Long) : void +existsReserva(connection : Connection,codigo : Long) : boolean +findReserva(connection : Connection,codigo : Long) : ReservaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getEntreFechas(connection : Connection,fecha1 : Calendar,fecha2 : Calendar,startIndex : int,count : int) : Collection +getByPersona(connection : Connection,dniPas : String,startIndex : int,count : int) : Collection +getByTemporal(connection : Connection,temporal : boolean,startIndex : int,count : int) : Collection +updateTemporal(connection : Connection,codigo : Long,temporal : boolean) : void +updateFechaRealizacion(connection : Connection,codigo : Long,fechaRealizacion : Calendar) : void MySQLReservaDAO +addReserva(connection : Connection,reservaVO : ReservaVO) : ReservaVO ReservaVO -serialVersionUID : long -dniPas : String -codigo : Long -fechaRealizacion : Calendar -temporal : boolean Figura 6.25: Diagrama del Paquete ’reserva’
    • 6.4. Arquitectura del Modelo 6.4.3.8. 126 Paquete ’factura’ SQLFacturaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLFacturaDAOFactory() -getDAOClass() : Class +getDAO() : SQLFacturaDAO <<interface>> SQLFacturaDAO +addFactura(connection : Connection,facturaVO : FacturaVO) : FacturaVO +removeFactura(connection : Connection,numeroFactura : Long) : void +findFactura(connection : Connection,numeroFactura : Long) : FacturaVO +existsFactura(connection : Connection,numeroFactura : Long) : boolean +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByCliente(connection : Connection,dniPas : String,startIndex : int,count : int) : Collection +getBetweenFechas(connection : Connection,earlierFecha : Calendar,laterFecha : Calendar,startIndex : int,count : int) : Collection +getByPagada(connection : Connection,pagada : boolean,startIndex : int,count : int) : Collection +getByBorrador(connection : Connection,borrador : boolean,startIndex : int,count : int) : Collection +getByClienteAndPagada(connection : Connection,dniPas : String,pagada : boolean,startIndex : int,count : int) : Collection +getByClienteAndBorrador(connection : Connection,dniPas : String,borrador : boolean,startIndex : int,count : int) : Collection +updateTotal(connection : Connection,numeroFactura : Long,newTotal : double) : void +updateTotalDescontado(connection : Connection,numeroFactura : Long,newTotalDescontado : double) : void +updateOfertasAplicadas(connection : Connection,numeroFactura : Long,ofertasAplicadas : String) : void +updateBorrador(connection : Connection,numeroFactura : Long,isBorrador : Boolean) : void +updatePagada(connection : Connection,numeroFactura : Long,isPagada : Boolean) : void +updateFecha(connection : Connection,numeroFactura : Long,fecha : Calendar) : void <<realize>> AbstractSQLFacturaDAO +getAll(connection : Connection,startIndex : int,count : int) : Collection +addFactura(connection : Connection,facturaVO : FacturaVO) : FacturaVO +existsFactura(connection : Connection,numeroFactura : Long) : boolean +findFactura(connection : Connection,numeroFactura : Long) : FacturaVO +getByBorrador(connection : Connection,borrador : boolean,startIndex : int,count : int) : Collection +getByCliente(connection : Connection,dniPas : String,startIndex : int,count : int) : Collection +getByClienteAndBorrador(connection : Connection,dniPas : String,borrador : boolean,startIndex : int,count : int) : Collection +getByClienteAndPagada(connection : Connection,dniPas : String,pagada : boolean,startIndex : int,count : int) : Collection +getBetweenFechas(connection : Connection,earlierFecha : Calendar,laterFecha : Calendar,startIndex : int,count : int) : Collection +getByPagada(connection : Connection,pagada : boolean,startIndex : int,count : int) : Collection +removeFactura(connection : Connection,numeroFactura : Long) : void +updateTotal(connection : Connection,numeroFactura : Long,newTotal : double) : void +updateBorrador(connection : Connection,numeroFactura : Long,isBorrador : Boolean) : void +updatePagada(connection : Connection,numeroFactura : Long,isPagada : Boolean) : void +updateTotalDescontado(connection : Connection,numeroFactura : Long,newTotalDescontado : double) : void +updateOfertasAplicadas(connection : Connection,numeroFactura : Long,ofertasAplicadas : String) : void +updateFecha(connection : Connection,numeroFactura : Long,fecha : Calendar) : void MySQLFacturaDAO +addFactura(connection : Connection,facturaVO : FacturaVO) : FacturaVO FacturaVO -serialVersionUID : long -dniPas : String -numeroFactura : Long -fecha : Calendar -totalDescontado : double -total : double -pagada : boolean -borrador : boolean -ofertasAplicadas : String Figura 6.26: Diagrama del Paquete ’factura’
    • 6.4. Arquitectura del Modelo 6.4.3.9. 127 Paquete ’tipooferta’ SQLTipoOfertaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLTipoOfertaDAOFactory() -getDAOClass() : Class +getDAO() : SQLTipoOfertaDAO <<interface>> SQLTipoOfertaDAO +addTipoOferta(connection : Connection,tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO +removeTipoOferta(connection : Connection,idTipo : Long) : void +existsTipoOferta(connection : Connection,idTipo : Long) : boolean +findTipoOferta(connection : Connection,idTipo : Long) : TipoOfertaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +updateDescripcion(connection : Connection,idTipo : Long,newDescripcion : String) : void +updateNombre(connection : Connection,idTipo : Long,newNombre : String) : void <<realize>> AbstractSQLTipoOfertaDAO +addTipoOferta(connection : Connection,tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO +removeTipoOferta(connection : Connection,idTipo : Long) : void +existsTipoOferta(connection : Connection,idTipo : Long) : boolean +findTipoOferta(connection : Connection,idTipo : Long) : TipoOfertaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +updateDescripcion(connection : Connection,idTipo : Long,newDescripcion : String) : void +updateNombre(connection : Connection,idTipo : Long,newNombre : String) : void MySQLTipoOfertaDAO +addTipoOferta(connection : Connection,tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO Figura 6.27: Diagrama del Paquete ’tipooferta’ TipoOfertaVO -serialVersionUID : long -idTipo : Long -nombre : String -descripcion : String
    • 6.4. Arquitectura del Modelo 6.4.3.10. 128 Paquete ’oferta’ SQLOfertaDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLOfertaDAOFactory() -getDAOClass() : Class +getDAO() : SQLOfertaDAO <<interface>> hotel::modelo::modelooferta::oferta::dao::SQLOfertaDAO +addOferta(connection : Connection,ofertaVO : OfertaVO) : OfertaVO +removeOferta(connection : Connection,idOferta : Long) : void +existsOferta(connection : Connection,idOferta : Long) : boolean +findOferta(connection : Connection,idOferta : Long) : OfertaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByIdTipo(connection : Connection,idTipo : Long,startIndex : int,count : int) : Collection +getByBorrador(connection : Connection,borrador : boolean,startIndex : int,count : int) : Collection +getByPublicadaActual(connection : Connection,startIndex : int,count : int) : Collection +getByDesactivada(connection : Connection,desactivada : boolean,startIndex : int,count : int) : Collection +getOfertasEnFecha(connection : Connection,fecha : Calendar,startIndex : int,count : int) : Collection +updateDescuento(connection : Connection,idOferta : Long,newDescuento : double) : void +updateDescripcion(connection : Connection,idOferta : Long,newDescripcion : String) : void +updateFechaInicio(connection : Connection,idOferta : Long,fechaInicio : Calendar) : void +updateFechaFin(connection : Connection,idOferta : Long,fechaFin : Calendar) : void +updateRegla(connection : Connection,idOferta : Long,newRegla : String) : void +updateBorrador(connection : Connection,idOferta : Long,borrador : boolean) : void +updateDesactivada(connection : Connection,idOferta : Long,desactivada : boolean) : void <<realize>> AbstractSQLOfertaDAO +addOferta(connection : Connection,ofertaVO : OfertaVO) : OfertaVO +removeOferta(connection : Connection,idOferta : Long) : void +existsOferta(connection : Connection,idOferta : Long) : boolean +findOferta(connection : Connection,idOferta : Long) : OfertaVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByIdTipo(connection : Connection,idTipo : Long,startIndex : int,count : int) : Collection +getByBorrador(connection : Connection,borrador : boolean,startIndex : int,count : int) : Collection +getByPublicadaActual(connection : Connection,startIndex : int,count : int) : Collection +getByDesactivada(connection : Connection,desactivada : boolean,startIndex : int,count : int) : Collection +getOfertasEnFecha(connection : Connection,fecha : Calendar,startIndex : int,count : int) : Collection +updateDescuento(connection : Connection,idOferta : Long,newDescuento : double) : void +updateDescripcion(connection : Connection,idOferta : Long,newDescripcion : String) : void +updateFechaInicio(connection : Connection,idOferta : Long,fechaInicio : Calendar) : void +updateFechaFin(connection : Connection,idOferta : Long,fechaFin : Calendar) : void +updateRegla(connection : Connection,idOferta : Long,newRegla : String) : void +updateBorrador(connection : Connection,idOferta : Long,borrador : boolean) : void +updateDesactivada(connection : Connection,idOferta : Long,desactivada : boolean) : void MySQLOfertaDAO +addOferta(connection : Connection,ofertaVO : OfertaVO) : OfertaVO OfertaVO -serialVersionUID : long -idOferta : Long -descuento : double -descripcion : String -fechaInicio : Calendar -fechaFin : Calendar -reglaACumplir : String -idTipo : Long -borrador : boolean -desactivada : boolean Figura 6.28: Diagrama del Paquete ’oferta’
    • 6.4. Arquitectura del Modelo 6.4.3.11. 129 Paquete ’aplicablea’ SQLAplicableADAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLAplicableADAOFactory() -getDAOClass() : Class +getDAO() : SQLAplicableADAO <<interface>> SQLAplicableADAO +addAplicableA(connection : Connection,aplicableAVO : AplicableAVO) : AplicableAVO +removeAplicableA(connection : Connection,idTipo : Long,nombre : String) : void +existsAplicableA(connection : Connection,idTipo : Long,nombre : String) : boolean +findAplicableA(connection : Connection,idTipo : Long,nombre : String) : AplicableAVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByIdTipo(connection : Connection,idTipo : Long,startIndex : int,count : int) : Collection +getByNombre(connection : Connection,nombre : String,startIndex : int,count : int) : Collection +updateCantidadMin(connection : Connection,idTipo : Long,nombre : String,cantidadMin : Long) : void <<realize>> AbstractSQLAplicableADAO +addAplicableA(connection : Connection,aplicableAVO : AplicableAVO) : AplicableAVO +removeAplicableA(connection : Connection,idTipo : Long,nombre : String) : void +existsAplicableA(connection : Connection,idTipo : Long,nombre : String) : boolean +findAplicableA(connection : Connection,idTipo : Long,nombre : String) : AplicableAVO +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByIdTipo(connection : Connection,idTipo : Long,startIndex : int,count : int) : Collection +getByNombre(connection : Connection,nombre : String,startIndex : int,count : int) : Collection +updateCantidadMin(connection : Connection,idTipo : Long,nombre : String,cantidadMin : Long) : void MySQLAplicableADAO +addAplicableA(connection : Connection,aplicableAVO : AplicableAVO) : AplicableAVO Figura 6.29: Diagrama del Paquete ’aplicablea’ AplicableAVO -serialVersionUID : long -idTipo : Long -nombre : String -cantidadMin : Long
    • 6.4. Arquitectura del Modelo 6.4.3.12. 130 Paquete ’incompatiblecon’ SQLIncompatibleConDAOFactory -DAO_CLASS_NAME_PARAMETER : String -daoClass : Class <<create>> -SQLIncompatibleConDAOFactory() -getDAOClass() : Class +getDAO() : SQLIncompatibleConDAO <<interface>> SQLIncompatibleConDAO +addIncompatibleCon(connection : Connection,incompatibleConVO : IncompatibleConVO) : IncompatibleConVO +removeAIncompatibleConB(connection : Connection,idTipoA : Long,idTipoB : Long) : void +existsAIncompatibleConB(connection : Connection,idTipoA : Long,idTipoB : Long) : boolean +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByIncompatibleConA(connection : Connection,idTipoA : Long,startIndex : int,count : int) : Collection <<realize>> AbstractSQLIncompatibleConDAO +addIncompatibleCon(connection : Connection,incompatibleConVO : IncompatibleConVO) : IncompatibleConVO +removeAIncompatibleConB(connection : Connection,idTipoA : Long,idTipoB : Long) : void +existsAIncompatibleConB(connection : Connection,idTipoA : Long,idTipoB : Long) : boolean +getAll(connection : Connection,startIndex : int,count : int) : Collection +getByIncompatibleConA(connection : Connection,idTipoA : Long,startIndex : int,count : int) : Collection MySQLIncompatibleConDAO +addIncompatibleCon(connection : Connection,incompatibleConVO : IncompatibleConVO) : IncompatibleConVO IncompatibleConVO -serialVersionUID : long -idTipo : Long -idTipoIncomp : Long Figura 6.30: Diagrama del Paquete ’incompatiblecon’
    • 6.4. Arquitectura del Modelo 6.4.4. 131 Descripci´n de los Subsistemas o En los siguientes apartados se detallar´n todos los subsistemas que forman la aplicaci´n. a o El primer subsistema que se tratar´ ser´ el de gesti´n de Usuarios y Clientes, encargado a a o de dar de alta, baja, modificaci´n de datos, b´squeda de clientes, etc. Este subsistema o u junto con el de Reservas son los dos que se desarrollan en la primera iteraci´n de la fase de o construcci´n durante la implementaci´n. Un vez desarrollados estos dos sistemas se tiene o o una primera versi´n del software que ya se puede utilizar y probar. o En una segunda iteraci´n se implementa el subsistema de Gesti´n de Facturas, ya que o o est´ muy relacionado con la Gesti´n de Reservas. Sin embargo este sistema utiliza el a o Sistema de Ofertas del que se habla en la p´gina 166, por lo que, aunque se implementa a m´s tarde, ya habr´ que definir en un principio la interfaz que va a utilizar para ofrecer a a servicios a los subsistemas. En la siguiente iteraci´n se desarrollar´ el subsistema de Gesti´n de Ofertas, que ya que o a o tambi´n est´ relacionado con el de las Facturas, es una buena idea implementarlo en este e a punto. Por ultimo se desarrollar´ la Gesti´n de Habitaciones, que aunque es un sistema que no ´ a o es complicado, no se puede dejar atr´s. a 6.4.4.1. Gesti´n de Usuarios y Clientes o En esta secci´n se mostrar´ como es el desarrollo de los casos de uso Gesti´n de Usuarios o a o Web y Gesti´n de Clientes. Como se ha podido observar en la descripci´n de estos casos de o o uso, los dos conjuntos de casos son muy parecidos, simplemente cambian algunos apartados de los casos de uso o se a˜aden otros nuevos, y los actores que los llevan a cabo. Por n esta similitud a la hora de llevarse a cabo, se juntaron esos dos conjuntos en el mismo subsistema. Aunque a la hora de implementarlo se han dividido de nuevo, de esta forma se usa el patr´n Session Facade en ambos conjuntos de casos de uso. o
    • 6.4. Arquitectura del Modelo 132 De aqu´ en adelante se mostrar´ como se organizan las clases que forman este subsistema ı a y luego se aclarar´ el cometido que tiene cada una de ellas. En las figuras 6.31 y 6.32 a se muestra unos diagramas sencillos de la Gesti´n de Usuarios y en las 6.33 y 6.34 los o diagramas de la Gesti´n de Clientes. o <<interface>> UsuariosWebFacade +autenticar(userName : String,userPassword : String) : PersonaVO +altaUsuario(personaVO : PersonaVO) : PersonaVO +bajaUsuario(dniPasPersona : String) : void +modificarDatosUsuario(personaVO : PersonaVO) : PersonaVO +getDatos(dniPasPersona : String) : PersonaVO +getDatos() : PersonaVO actions <<realize>> GeneralUsuariosWebFacade <<create>> +GeneralUsuariosWebFacade() +bajaUsuario(dniPasPersona : String) : void +modificarDatosUsuario(personaVO : PersonaVO) : PersonaVO +altaUsuario(personaVO : PersonaVO) : PersonaVO +getDatos(dniPasPersona : String) : PersonaVO +getDatos() : PersonaVO +autenticar(userName : String,userPassword : String) : PersonaVO exceptions Figura 6.31: Diagrama Simple de Gesti´n de Usuarios o <<interface>> PlainAction +execute(connection : Connection) : Object <<interface>> TransactionalPlainAction AltaUsuarioAction <<create>> +AltaUsuarioAction(personaVO : PersonaVO) +execute(connection : Connection) : Object ModificarDatosUsuarioAction <<create>> +ModificarDatosUsuarioAction(personaVO : PersonaVO) +execute(connection : Connection) : Object <<interface>> NonTransactionalPlainAction BajaUsuarioAction <<create>> +BajaUsuarioAction(dniPas : String) +execute(connection : Connection) : Object GetDatosAction <<create>> +GetDatosAction(dniPasPersona : String) +execute(connection : Connection) : Object AutenticarAction UserNameAlreadyInUseException <<create>> +AutenticarAction(userName : String,userPassword : String) +execute(connection : Connection) : Object PersonAlreadyExistsException AuthenticationFailException Figura 6.32: Actions y Exceptions de Gesti´n de Usuarios o
    • 6.4. Arquitectura del Modelo 133 En estos diagramas se puede observar el uso de los patrones Session Facade y Business Delegate. La interfaz para acceder a este subsistema es UsuariosWebFacade, implementado por GeneralUsuariosWebFacade, el cual se implementa en t´rminos de DAOs. Esta fachada e proporciona a las dem´s capas que la quieran utilizar una serie de operaciones. Estas a operaciones que ofrece, para evitar caer en una clase enorme, delegan su funcionamiento en las acciones correspondientes del subpaquete Actions. A continuaci´n se explicar´ el o a funcionamiento de cada una de las acciones. Adem´s de usar unas acciones para implementar sus m´todos, esta fachada tambi´n a e e lanza una serie de excepciones personalizadas, CustomException, que a diferencia de las excepciones normales de Java que se utilizan para describir un caso de error en el sistema, estas se emplear´n para proporcionar informaci´n a las capas superiores acerca del estado a o con el que finaliz´ la operaci´n, sin que este estado tenga que ser un estado de error de o o la aplicaci´n. En el caso de UsuariosWebFacade se utilizar´n excepciones para informar si o a el nombre de usuario est´ en uso, si la autenticaci´n ha sido fallida y si el usuario que se a o pretende crear o modificar ya existe en el sistema. Las acciones en base a las cual se implementan las operaciones de UsuariosWebFacade, podr´n clasificarse como transaccionales y no transaccionales dependiendo si es necesario a que la operaci´n se realice de forma at´mica o no, y son las siguientes: o o AltaUsuarioAction Esta acci´n es la encargada de dar de alta un nuevo usuario o en el sistema. Para ello necesita que se le pasen los par´metros necesarios para a tal operaci´n, es decir, los datos del nuevo usuario, estos ir´n encapsulados o a en un objeto PersonaVO, que como ya se ha visto anterioremente, sigue el patr´n Value Object (VO) y proporciona m´todos para lectura y escritura de o e sus atributos. Lo primero que se debe hacer es comprobar si el nuevo DNI ya existe en la base de datos, esto lo hacemos gracias a PersonaDAO que nos ofrece m´todos para e insertar, modificar, consultar y eliminar datos de la base de datos. Si el DNI
    • 6.4. Arquitectura del Modelo 134 ya existe se lanzar´ una excepci´n indicando este suceso, y si no se contin´a a o u comprobando si existe el nombre de usuario, si no existe entonces se procede a la inserci´n de los datos del nuevo usuario en la base de datos utilizando o PersonaDAO BajaUsuarioAction Es la encargada de dar de baja un usuario del sistema. Para ello es necesario pasarle el DNI del cliente que se desea dar de baja. Luego se utiliza PersonaDAO para actualizar el atributo ’usuarioConf’ poniendo un ’false’. En realidad no se eliminan sus datos del sistema, pero a partir de ese momento deja de ser usuario de este. ModificarDatosUsuarioAction Se encarga de actualizar los datos personales de un usuario. Para ello necesita que se le pasen todos los datos de nuevo, como si el usuario se fuera a dar de alta, mediante un objeto PersonaVO. Luego se recuperan los datos del usuario que est´n almacenados y se comparan a uno a uno con los nuevos, aquellos que no coincidan se actualizan utilizando PersonaDAO. GetDatosAction Se encarga de recuperar los datos personales de un usuario. Para ello necesita que se le pase el DNI del usuario del que se desea la informaci´n. o A continuaci´n se recuperan los datos del usuario que est´n almacenados. o a AutenticarAction Se encarga de comprobar si el usuario existe en el sistema, y de ser as´ devolver un objeto PersonaVO con sus datos personales. Para realizar ı esta operaci´n necesita el nombre de usuario y la contrase˜a del cliente. o n Lo primero que realiza la acci´n es recuperar los datos de un usuario que tenga o ese nombre de usuario y esa contrase˜a, si la recuperaci´n falla o el usuario n o est´ se˜alado como ’no confirmado’ entonces se lanza la excepci´n Autenticaa n o tionFailException, que indica que no se pudo autenticar la identidad del cliente.
    • 6.4. Arquitectura del Modelo 135 A continuaci´n en la figura 6.33 se muestra el esquema de las clases que forman el Session o Facade ’ClientesFacade’ y las acciones en las que sus m´todos delegan su funcionamiento. e <<interface>> ClientesFacade +altaCliente(personaVO : PersonaVO) : PersonaVO +bajaCliente(dniPas : String) : void +modificarDatosCliente(personaVO : PersonaVO) : PersonaVO +buscarClientes(name : String,surname : String,dniPas : String,startIndex : int,count : int) : PersonaCollectionChunkVO +getDatos(dniPasPersona : String) : PersonaVO +getDatos() : PersonaVO <<realize>> GeneralClientesFacade -serialVersionUID : long -dataSource : DataSource -personaVO : PersonaVO <<create>> +GeneralClientesFacade() +modificarDatosCliente(personaVO : PersonaVO) : PersonaVO +altaCliente(personaVO : PersonaVO) : PersonaVO +bajaCliente(dniPas : String) : void +getDatos(dniPasPersona : String) : PersonaVO +getDatos() : PersonaVO +buscarClientes(name : String,surname : String,dniPas : String,startIndex : int,count : int) : PersonaCollectionChunkVO actions exceptions vo Figura 6.33: Diagrama Simple de Gesti´n de Clientes o
    • 6.4. Arquitectura del Modelo 136 <<interface>> PlainAction +execute(connection : Connection) : Object <<interface>> NonTransactionalPlainAction <<interface>> TransactionalPlainAction BajaClienteAction AltaClienteAction <<create>> +BajaClienteAction(dniPas : String) +execute(connection : Connection) : Object <<create>> +AltaClienteAction(personaVO : PersonaVO) +execute(connection : Connection) : Object GetDatosAction ModificarDatosClienteAction <<create>> +GetDatosAction(dniPasPersona : String) +execute(connection : Connection) : Object <<create>> +ModificarDatosClienteAction(personaVO : PersonaVO) +execute(connection : Connection) : Object BuscarClientesAction <<create>> +BuscarClientesAction(name : String,surname : String,dniPas : String,startIndex : int,count : int) +execute(connection : Connection) : Object PersonNotFoundException UserNameAlreadyInUseException PersonAlreadyExistsException <<call>> <<create>> PersonaCollectionChunkVO <<create>> +PersonaCollectionChunkVO(colPersonas : Collection,index : int,more : Boolean) +getColPersonas() : Collection +getIndex() : int +getHasMore() : Boolean Figura 6.34: Actions y Exceptions de Gesti´n de Clientes o En estos diagramas se puede observar de nuevo el uso de los patrones Session Facade y Business Delegate. La interfaz para acceder a este subsistema es ClientesFacade, implementado por GeneralClientesFacade. Al igual que en el Session Facade anterior, los m´todos de la fachada delegan su funcionamiento en las acciones correspondientes del e subpaquete Actions. A continuaci´n se explicar´ el funcionamiento de cada una de las o a acciones. Adem´s de usar unas acciones para implementar sus m´todos, esta fachada tambi´n a e e lanza CustomException para proporcionar informaci´n a las capas superiores acerca del o estado con el que finaliz´ la operaci´n. En este caso se usar´n excepciones para informar si o o a el nombre de usuario del cliente est´ en uso, si el cliente que se pretende crear o modificar a ya existe en el sistema, o si un cliente buscado no se ha encontrado.
    • 6.4. Arquitectura del Modelo 137 Las acciones en base a las cual se implementan las operaciones de ClientesFacade, tambi´n podr´n clasificarse como transaccionales y no transaccionales dependiendo si es nee a cesario que la operaci´n se realice de forma at´mica o no, y son las siguientes: o o AltaClienteAction Esta acci´n es la encargada de dar de alta un nuevo cliente o en el sistema. Para ello necesita que se le pasen los par´metros necesarios para a tal operaci´n, es decir, los datos del nuevo cliente, estos ir´n encapsulados en o a un objeto PersonaVO, que como ya se ha visto anterioremente, aunque para el caso de dar de alta un nuevo cliente no ser´n obligatorios todos los datos que a lo eran para dar de alta a un usuario. Lo primero que se debe hacer es comprobar si el nuevo DNI ya existe en la base de datos utilizando PersonaDAO. Si el DNI ya existe se lanzar´ una excepci´n a o indicando este suceso, y sino se contin´a comprobando si existe el nombre de u usuario, si no existe entonces se procede a la inserci´n de los datos del nuevo o cliente en la base de datos utilizando de nuevo PersonaDAO BajaClienteAction Es la encargada de dar de baja un usuario del sistema. Para ello es necesario pasarle el DNI del cliente que se desea dar de baja. Primero se comprueba si existe el DNI, sino se lanza una excepci´n, y luego o se utiliza PersonaDAO para actualizar el atributo ’usuarioConf’ poniendo un ’false’. En realidad no se eliminan sus datos del sistema, pero a partir de ese momento deja de ser cliente. ModificarDatosClienteAction Se encarga de actualizar los datos personales de un cliente. Para ello necesita que se le pasen todos los datos de nuevo, como si el cliente se fuera a dar de alta, mediante un objeto PersonaVO. Luego se recuperan los datos del cliente que est´n almacenados y se comparan a uno a uno con los nuevos, aquellos que no coincidan se actualizan utilizando PersonaDAO.
    • 6.4. Arquitectura del Modelo 138 GetDatosAction Se encarga de recuperar los datos personales de un cliente. Para ello necesita que se le pase el DNI del cliente del que se desea la informaci´n. o A continuaci´n se recuperan los datos del cliente que est´n almacenados. o a BuscarClientesAction Esta acci´n es la encargada de recuperar una lista de clieno tes que concuerden con unos par´metros de b´squeda, en este caso se podr´ busa u a car por nombre, apellidos y/o DNI, se podr´ hacer cualquier combinaci´n que a o se desee. Para llevar a cabo esta operaci´n es necesario comprobar cu´les son los campos o a por los que se quiere buscar, ya que el DAO PersonaDAO necesita que se le indique mediante valores ’boolean’ aquellos campos para los que tiene que realizar la consulta. Una vez hecho esto PersonaDAO recupera la lista de clientes que concuerdan con los criterios. 6.4.4.2. Gesti´n de Reservas o En esta secci´n se mostrar´ c´mo es el desarrollo de los casos de uso Gesti´n de Reservas. o a o o Como en los casos anteriores se utiliza el patr´n Session Facade para implementar este o subsistema. Entre las operaciones de este sistema cabe destacar que debe permitir comprobar si existe alguna habitaci´n libre de un tipo determinado para una serie de d´ Esta operaci´n no o ıas. o implementa ning´n caso de uso espec´ u ıfico pero es necesaria para realizar comprobaciones a la hora de realizar reservas. De aqu´ en adelante se mostrar´ como se organizan las clases que forman este subsistema ı a y luego se aclarar´ el cometido que tiene cada una de ellas. En las figuras 6.35 y 6.36 se a muestra unos diagramas sencillos de la Gesti´n de Reservas. o
    • 6.4. Arquitectura del Modelo 139 <<interface>> ReservasWebFacade +checkDisponible(reserva : ReservaFromToTipoHabitacionChunkVO) : boolean +checkDisponible(reserva : ReservaFromToTipoHabitacionChunkVO,numeroHabs : Long) : boolean +crearReserva(dniPas : String,reservaTipoHabitacion : Collection) : ReservaCompletaChunkVO +getReservaCompleta(codReserva : Long) : ReservaCompletaChunkVO +modificarDatosReserva(lastReserva : ReservaCompletaChunkVO,newReserva : ReservaCompletaChunkVO) : ReservaCompletaChunkVO +getReservas(dniPas : String,index : int,count : int) : ReservasCollectionChunkVO +checkHabitacionesLibres(From : Calendar,To : Calendar) : Map <<realize>> GeneralReservasWebFacade -dataSource : DataSource <<create>> +GeneralReservasWebFacade() +checkDisponible(reserva : ReservaFromToTipoHabitacionChunkVO) : boolean +crearReserva(dniPas : String,reservaTipoHabitacion : Collection) : ReservaCompletaChunkVO +getReservaCompleta(codReserva : Long) : ReservaCompletaChunkVO +modificarDatosReserva(lastReserva : ReservaCompletaChunkVO,newReserva : ReservaCompletaChunkVO) : ReservaCompletaChunkVO +checkDisponible(reserva : ReservaFromToTipoHabitacionChunkVO,numeroHabs : Long) : boolean +getReservas(dniPas : String,index : int,count : int) : ReservasCollectionChunkVO +checkHabitacionesLibres(from : Calendar,to : Calendar) : Map vo actions ReservasCollectionChunkVO LineaDeReservaChunkVO ReservaCompletaChunkVO exceptions ReservaFromToTipoHabitacionChunkVO ReservaChunkVO Figura 6.35: Diagrama Simple de Gesti´n de Reservas o
    • 6.4. Arquitectura del Modelo 140 ModificarReservaAction <<create>> +ModificarReservaAction(lastReserva : ReservaCompletaChunkVO,newReserva : ReservaCompletaChunkVO) +execute(connection : Connection) : Object IllegalReservationChangeException CrearReservaAction <<create>> +CrearReservaAction(dniPas : String,reserva : Collection) +execute(connection : Connection) : Object EmptyReservationException <<interface>> TransactionalPlainAction SomeDayNotAvailableException <<interface>> PlainAction +execute(connection : Connection) : Object <<interface>> NonTransactionalPlainAction CheckDisponibleAction <<create>> +CheckDisponibleAction(reserva : ReservaFromToTipoHabitacionChunkVO) +execute(connection : Connection) : Object NoRoomsOfEspecifiedTypeException CheckDisponibleQuantityAction <<create>> +CheckDisponibleQuantityAction(reserva : ReservaFromToTipoHabitacionChunkVO,quantity : Long) +execute(connection : Connection) : Object IllegalCheckException CheckHabitacionesLibresAction <<create>> +CheckHabitacionesLibresAction(from : Calendar,to : Calendar) +execute(connection : Connection) : Object NoReservationFoundException GetReservaCompletaAction <<create>> +GetReservaCompletaAction(codReserva : Long) +execute(connection : Connection) : Object GetReservasAction <<create>> +GetReservasAction(dniPas : String,index : int,count : int) +execute(connection : Connection) : Object Figura 6.36: Actions y Exceptions de Gesti´n de Reservas o
    • 6.4. Arquitectura del Modelo 141 En estos diagramas se puede ver c´mo se vuelven a usar los patrones Session Facade o y Business Delegate. La interfaz para acceder a este subsistema es ReservasWebFacade, implementado por GeneralReservasWebFacade. Al igual que en el Session Facade anterior, los m´todos de la fachada delegan su funcionamiento en las acciones correspondientes del e subpaquete Actions. A continuaci´n se explicar´ el funcionamiento de cada una de las o a acciones. Adem´s de usar unas acciones para implementar sus m´todos, esta fachada tambi´n a e e lanza CustomException para proporcionar informaci´n a las capas superiores acerca del o estado con el que finaliz´ la operaci´n. En este caso se usar´n excepciones para informar o o a si no hay habitaciones libres de un tipo solicitado, si una reserva que se desea crear o modificar est´ vac´ si se quiere crear o cambiar una reserva pero alguno de los d´ a ıa, ıas est´ ya ocupado, si una reserva no se puede cambiar o si no se encuentra una reserva a buscada. Por otro lado, esta fachada manejar´ unos objetos especiales, los Custom Value Objects. a Estos objetos estar´n localizados en el subpaquete ’vo’ y tendr´n como cometido ofrecer a a a las capas superiores un conjunto de los atributos de un VO ya existente, o varios atributos de diferentes VOs agrupados, con esto lo que se pretente es pasar a la capa superior unicamente los datos que necesita. Otro caso para lo que se utilizan los Custom Value Ob´ jects es para ’paginar’ los resultados de una lista, por ejemplo, si se quieren recuperar 100 valores de la base de datos, estos se encapsular´n en un objeto que adem´s contendr´ otra a a a informaci´n como: si hay, o no, m´s elementos para hacer una siguiente b´squeda. o a u Las acciones en base a las cuales se implementan las operaciones de ReservasFacade, tambi´n podr´n clasificarse como transaccionales y no transaccionales dependiendo si es e a necesario que la operaci´n se realice de forma at´mica o no, y son las siguientes: o o CrearReservaAction Esta acci´n es la encargada de crear una nueva reserva. Para o esto necesita que se le pasen un conjunto de l´ ıneas de reserva y el DNI del cliente que la desea realizar.
    • 6.4. Arquitectura del Modelo 142 Las l´ ıneas de reserva que se le deben pasar a esta acci´n tienen que ser lo menos o concretas posibles, es decir, no se indicar´ la habitaci´n, ya que estas se asignan a o una vez que se comprueben si est´n libres. Para pasar estos datos se crea un a nuevo objeto que es ’ReservaFromToTipoHabitacionChunkVO’ que lo unico ´ que representa es: una fecha de llegada, fecha de salida y tipo de habitaci´n o al que se destina. Este objeto tambi´n proporcionar´ m´todos necesarios para e a e comprobar si una reserva coincide en fechas con otra. Luego la acci´n tiene que comprobar si hay habitaciones libres de alguna hao bitaci´n del tipo deseado para los d´ indicados. Si es as´ se escoge alguna o ıas ı, de las habitaciones libres para los d´ que se desean y se guarda la l´ ıas ınea de reserva. Esto se hace con todas las l´ ıneas de reserva y a continuaci´n se crean: o una nueva factura calculando todos los totales y una reserva. Al terminar se devuelve un objeto ’ReservaCompletaChunkVO’ donde se encapsulan todas las l´ ıneas de reserva, los datos de la reserva, n´mero de la factura, u etc. ModificarReservaAction Esta acci´n hace lo mismo que ’CrearReservaAction’, o pero antes de comprobar las habitaciones libres divide el conjunto de l´ ıneas de reserva pasadas en: las que ya existen en la base de datos, las que no existen, y las que exist´ y hay que eliminar. Una vez hechas esas comprobaciones y ıan sabiendo que se pueden crear las nuevas l´ ıneas de reserva, se procede a eliminar y crear las l´ ıneas que proceda y a actualizar los totales en la factura. GetReservaCompletaAction Se encarga de recuperar todos los datos relativos a una reserva, para ello le hay que pasar el c´digo de la reserva. Luego la acci´n, o o utilizando los DAOs pertinentes, recupera las l´ ıneas de reserva, los datos de la reserva y los datos de la factura. A continuaci´n lo encapsula todo en un objeto o ’ReservaCompletaChunkVO’ y lo devuelve.
    • 6.4. Arquitectura del Modelo 143 GetReservasAction Se encarga de recuperar los datos de las reservas de un cliente. Para eso se le deben pasar el DNI del cliente, desde d´nde se desea recuperar o la lista de reservas y cu´ntas se quiere que se devuelvan. a Con estos datos, la acci´n consigue de la base de datos las reservas deseadas y o las encapsula en un objeto ’ReservasCollectionChunkVO’ que ser´ el que se le a pase a la capa superior, este objeto, como ya se ha mencionado antes, es el que se utiliza para ’paginar’ una lista de resultados. CheckDisponibleAction Esta acci´n es la encargada de comprobar si hay habitao ciones libres para un rango de fechas determinado y para un tipo de habitaci´n. o Para esto se le debe pasar un objeto ’ReservaFromToTipoHabitacionChunkVO’ que contiene las fechas y el tipo de habitaci´n que se quiere comprobar. o La acci´n comprueba si para los d´ indicados existe alguna habitaci´n que no o ıas o est´ ocupada, de ser as´ devuelve un valor de tipo ’boolean’ indicando que hay e ı al menos una habitaci´n disponible de ese tipo para esas fechas. o CheckDisponibleQuantityAction Esta acci´n es la encargada de comprobar si o hay habitaciones libres para un rango de fechas, para un tipo de habitaci´n y o una cantidad determinada. Para esto se le debe pasar un objeto ’ReservaFromToTipoHabitacionChunkVO’ que contiene las fechas, el tipo de habitaci´n que o se quiere comprobar y el n´mero de habitaciones que se desean. u La acci´n comprueba si para los d´ indicados existe el n´mero de habitaci´nes o ıas u o indicado que no est´n ocupadas, de ser as´ devuelve un valor de tipo ’boolean’ e ı indicando que hay al menos ese n´mero de habitaciones disponibles de ese tipo u para esas fechas. CheckHabitacionesLibresAction Esta acci´n es la encargada de comprobar cu´ntas o a habitaciones hay libres para un rango de fechas. Se le pasa una fecha de llegada y una de salida.
    • 6.4. Arquitectura del Modelo 144 Luego comprueba para todos los tipos de habitaciones cu´ntas hay libres para a esas fechas y devuelve un conjunto de tipos de habitaci´n y n´mero de habitao u ciones libres. 6.4.4.3. Gesti´n de Habitaciones o En esta secci´n se mostrar´ c´mo es el desarrollo de los casos de uso Gesti´n de Habitao a o o ciones. Como en los casos anteriores se utiliza el patr´n Session Facade para implementar o este subsistema. De aqu´ en adelante se mostrar´ c´mo se organizan las clases que forman este subsistema ı a o y luego se aclarar´ el cometido que tiene cada una de ellas. En las figuras 6.37 y 6.38 se a muestra unos diagramas sencillos de la Gesti´n de Habitaciones. o
    • 6.4. Arquitectura del Modelo 145 <<interface>> HabitacionesFacade +getRoom(number : Long) : HabitacionVO +getRoomsOfType(typeId : Long) : Collection +getRoomComplete(number : Long,startIndex : int,count : int) : HabitacionCompletaChunkVO +addRoom(habitacion : HabitacionVO,idTipo : Long) : HabitacionVO +updateRoom(habitacion : HabitacionVO,idTipo : Long) : HabitacionVO +addRoom(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO) : HabitacionCompletaChunkVO +updateRoom(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO) : HabitacionCompletaChunkVO +deleteRoom(number : Long) : void +getRooms(index : int,count : int) : HabitacionesCollectionChunkVO +addRoomType(tipoHabitacion : TipoHabitacionVO) : TipoHabitacionVO +updateRoomType(tipohabitacion : TipoHabitacionVO) : TipoHabitacionVO +getRoomType(typeId : Long) : TipoHabitacionVO +getAllRoomTypes() : Collection +addIncident(incidencia : IncidenciaVO,number : Long) : IncidenciaVO +getIncident(number : Long,idInc : Long) : IncidenciaVO +getAllIncidentsOfRoom(number : Long,index : int,count : int) : IncidenciasCollectionChunkVO <<realize>> GeneralHabitacionesFacade -dataSource : DataSource <<create>> +GeneralHabitacionesFacade() +addIncident(incidencia : IncidenciaVO,number : Long) : IncidenciaVO +addRoom(habitacion : HabitacionVO,idTipo : Long) : HabitacionVO +updateRoom(habitacion : HabitacionVO,idTipo : Long) : HabitacionVO +addRoom(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO) : HabitacionCompletaChunkVO +updateRoom(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO) : HabitacionCompletaChunkVO +addRoomType(tipoHabitacion : TipoHabitacionVO) : TipoHabitacionVO +updateRoomType(tipoHabitacion : TipoHabitacionVO) : TipoHabitacionVO +deleteRoom(number : Long) : void +getAllIncidentsOfRoom(number : Long,index : int,count : int) : IncidenciasCollectionChunkVO +getAllRoomTypes() : Collection +getRooms(index : int,count : int) : HabitacionesCollectionChunkVO +getIncident(number : Long,idInc : Long) : IncidenciaVO +getRoom(number : Long) : HabitacionVO +getRoomComplete(number : Long,startIndex : int,count : int) : HabitacionCompletaChunkVO +getRoomType(typeId : Long) : TipoHabitacionVO +getRoomsOfType(typeId : Long) : Collection vo actions HabitacionCompletaChunkVO exceptions HabitacionesCollectionChunkVO IncidenciasCollectionChunkVO Figura 6.37: Diagrama Simple de Gesti´n de Habitaciones o
    • 6.4. Arquitectura del Modelo 146 AddRoomCompleteAction <<create>> +AddRoomCompleteAction(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO) +execute(connection : Connection) : Object UpdateRoomCompleteAction <<create>> +UpdateRoomCompleteAction(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO) +execute(connection : Connection) : Object AddRoomAction <<create>> +AddRoomAction(habitacion : HabitacionVO,idTipo : Long) +execute(connection : Connection) : Object DeleteRoomAction <<create>> +DeleteRoomAction(number : Long) +execute(connection : Connection) : Object UpdateRoomAction <<create>> +UpdateRoomAction(habitacion : HabitacionVO,idTipo : Long) +execute(connection : Connection) : Object <<interface>> TransactionalPlainAction UpdateRoomTypeAction <<create>> +UpdateRoomTypeAction(tipoHabitacion : TipoHabitacionVO) +execute(connection : Connection) : Object <<interface>> PlainAction +execute(connection : Connection) : Object AddRoomTypeAction <<create>> +AddRoomTypeAction(tipoHabitacion : TipoHabitacionVO) +execute(connection : Connection) : Object <<interface>> NonTransactionalPlainAction AddIncidentAction <<create>> +AddIncidentAction(incidencia : IncidenciaVO,number : Long) +execute(connection : Connection) : Object GetAllIncidentsOfRoomAction <<create>> +GetAllIncidentsOfRoomAction(number : Long,index : int,count : int) +execute(connection : Connection) : Object GetIncidentAction <<create>> +GetIncidentAction(number : Long,idInc : Long) +execute(connection : Connection) : Object GetAllRoomTypesAction <<create>> +GetAllRoomTypesAction() +execute(connection : Connection) : Object GetAllRoomsAction <<create>> +GetAllRoomsAction(index : int,count : int) +execute(connection : Connection) : Object GetRoomAction <<create>> +GetRoomAction(number : Long) +execute(connection : Connection) : Object GetRoomCompleteAction <<create>> +GetRoomCompleteAction(number : Long,startIndex : int,count : int) +execute(connection : Connection) : Object GetRoomsOfTypeAction <<create>> +GetRoomsOfTypeAction(idTipo : Long) +execute(connection : Connection) : Object GetRoomTypeAction <<create>> +GetRoomTypeAction(idTipo : Long) +execute(connection : Connection) : Object Figura 6.38: Actions de Gesti´n de Habitaciones o
    • 6.4. Arquitectura del Modelo 147 Al igual que en los subsistemas anteriores, en este se vuelven a utilizar los patrones Session Facade y Business Delegate. La interfaz para acceder a este subsistema es HabitacionesFacade, implementado por GeneralHabitacionesFacade. Al igual que en los Session Facade anteriores, los m´todos de la fachada delegan su funcionamiento en las acciones e del subpaquete Actions. A continuaci´n se explicar´ el funcionamiento de cada una de las o a acciones. Adem´s de usar unas acciones para implementar sus m´todos, esta fachada tambi´n a e e lanzar´ CustomException para proporcionar informaci´n a las capas superiores acerca del a o estado con el que finaliz´ la operaci´n. En este caso se usar´n excepciones para informar o o a si algo que se desea insertar ya existe o si lo que se quiere recuperar no se encuentra. Al igual que el caso de la Gesti´n de Reserva, esta fachada tambi´n manejar´ unos o e a objetos especiales, los Custom Value Objects. Este tipo de objetos, cuyo uso y cometido ya se ha mencionado en la explicaci´n del subsistema anterior, se encontrar´n en el subpaquete o a ’vo’. Las acciones en base a las cuales se implementan las operaciones de HabitacionesFacade, se podr´n clasificar como transaccionales y no transaccionales como ocurr´ en los dem´s a ıan a subsistemas. Estas acciones se explicar´n a continuaci´n muy brevemente debido a que no a o implementan procesos complejos: AddRoomTypeAction Esta acci´n se encarga de crear un nuevo tipo de habitao ci´n. Para ello se le pasan los datos del nuevo tipo de habitaci´n y utilizando o o los DAOs pertinentes inserta el nuevo tipo en la base de datos. AddRoomAction Al igual que la acci´n anterior, se encarga de crear una nueva o habitaci´n. Para esto necesita que se le pasen los datos de la habitaci´n y el o o tipo de habitaci´n al que pertenecer´. o a Primero se comprueba que el tipo de habitaci´n exista, si existe se guardan los o datos de la nueva habitaci´n, y sin´ se lanza una exepci´n indicando que el tipo o o o de habitaci´n no se ha encontrado. o
    • 6.4. Arquitectura del Modelo 148 AddRoomCompleteAction A veces puede que se quiera crear una habitaci´n y o el tipo de habitaci´n en el mismo momento. Esta acci´n da soporte para que o o eso se pueda realizar. Como se puede adivinar, en este caso se necesitar´n los a datos de la habitaci´n y del tipo de habitaci´n. o o Primero se intenta crear el tipo de habitaci´n, si el tipo existe, se lanza una o excepci´n para indicarlo, y sino, se procede a insertar los datos de la nueva o habitaci´n. o AddIncidentAction Si ocurriese alg´n percance en una de las habitaciones habr´ u ıa que registrarlo, esta acci´n permite guardar un incidente y relacionarlo con una o habitaci´n. Para realizarlo se le deben pasar los datos del incidente y el n´mero o u de habitaci´n en la que ha ocurrido. o Luego utilizando los DAOs necesarios inserta el nuevo incidente en la base de datos. UpdateRoomTypeAction Se encarga de actualizar los datos de un tipo de habitaci´n. Se le deben indicar los nuevos datos. o Primero se recuperan los datos almacenados, luego se comparan con los datos antiguos y s´lo se actualizan los que difieran. o UpdateRoomAction Se encarga de actualizar los datos de una habitaci´n. Se le o deben indicar los nuevos datos y el nuevo tipo de habitaci´n. o Primero se recuperan los datos almacenados, luego se comprueba si se debe actualizar el tipo de habitaci´n, y a continuaci´n se comparan los nuevos datos o o con los antiguos y s´lo se actualizan los que difieran. o UpdateRoomAction Se encarga de actualizar los datos de una habitaci´n y de o crear un nuevo tipo de habitaci´n para esta. Se le deben indicar los nuevos o datos de la habitaci´n y los del tipo de habitaci´n. o o
    • 6.4. Arquitectura del Modelo 149 Primero se recuperan los datos almacenados, luego se crea el nuevo tipo de habitaci´n, y a continuaci´n se comparan los nuevos datos con los antiguos y o o s´lo se actualizan los distintos. o DeleteRoomAction Esta acci´n es la encargada de eliminar una habitaci´n de la o o base de datos. Simplemente le hay que pasar el n´mero de la habitaci´n que se u o quiere borrar. Si la habitaci´n no existe se lanza una excepci´n indic´ndolo, y o o a sino se utiliza el DAO pertinente para eliminarla. GetAllIncidentsOfRoomAction Con esta acci´n se permite recuperar una lista o de los incidentes de una habitaci´n. Para ello hay que pasarle el n´mero de o u habitaci´n de la cual se desean los incidentes, desde d´nde se quiere que se o o recuperen y la cantidad. A continuaci´n la acci´n recupera los datos a trav´s de los DAOs y los encapsula o o e en un Custom Value Object, de esta forma, como ya se ha visto con las reservas, se consigue una paginaci´n de los resultados. o GetIncidentAction Esta acci´n es la encargada recuperar los datos de un incio dente. Para ello se le debe pasar la habitaci´n donde tuvo lugar y el n´mero de o u incidente. Con estos datos lo recupera y lo devuelve. GetAllRoomTypesAction Con esta acci´n se permite recuperar una lista de los o tipos de habitaci´n. o La acci´n simplemente recupera todos los tipos de habitaci´n y los devuelve a o o trav´s de un objeto Collection. Esta vez no necesitan ser paginados porque se e estiman pocos y se puede permitir enviarlos todos juntos. GetRoomTypeAction Esta acci´n se encarga de recuperar los datos de un tipo o de habitaci´n. Para ello hay que pasarle el identificador del tipo de habitaci´n o o del que se quieren los datos. La acci´n recupera los datos mediante los DAOs o pertinentes y los devuelve.
    • 6.4. Arquitectura del Modelo 150 GetAllRoomsAction Con esta acci´n se permite recuperar una lista de las hao bitaciones. Para esto la acci´n necesita que se le pase desde d´nde necesita la o o lista y la cantidad de habitaciones que se desean ver. La acci´n simplemente recupera todos las habitaciones y las devuelve a trav´s o e de un objeto HabitacionesCollectionChunkVO, para que luego pueda realizarse una paginaci´n del resultado. o GetRoomAction Esta acci´n se encarga de recuperar los datos de una habitaci´n. o o Para ello hay que pasarle el n´mero de la habitaci´n de la que se quieren u o los datos. La acci´n recupera los datos mediante los DAOs pertinentes y los o devuelve. GetRoomCompleteAction Esta acci´n se encarga de recuperar los datos de una o habitaci´n, las incidencias y los datos del tipo de habitaci´n. Para ello hay que o o pasarle el n´mero de la habitaci´n de la que se quieren los datos. u o La acci´n recupera los toda la informaci´n requerida mediante los DAOs que o o correspondan y lo devuelve todo encapsulado en un Costum Value Object. GetRoomsOfTypeAction Esta acci´n se encarga de recuperar todas las habitao ciones que pertenecen a un tipo de habitaci´n. Para ello se le pasa el identifio cador del tipo de habitaci´n. o La acci´n recupera todas las habitaciones del tipo de habitaci´n indicado y las o o devuelve todas juntas utilizando un objeto Collection. 6.4.4.4. Gesti´n de Ofertas o En esta secci´n se mostrar´ c´mo es el desarrollo de los casos de uso Gesti´n de Ofertas. o a o o Como en los subsistemas anteriores se utilizan los patrones Session Facade y Business Delegate para desarrollarlo De aqu´ en adelante se mostrar´ c´mo se organizan las clases que forman este subsistema ı a o y luego se aclarar´ el cometido que tiene cada una de ellas. El subsistema se divide en dos a
    • 6.4. Arquitectura del Modelo 151 fachadas, una en la que se manejan los tipos de oferta, y otra en la cual se gestionan las ofertas. En las figuras 6.39 y 6.40 se observa c´mo se organizan las clases de la Session o Facade que gestiona los tipos de oferta, y en las figuras 6.41 y 6.42 se muestra unos diagramas sencillos de la Gesti´n de Ofertas. o <<interface>> TipoOfertaFacade +crearTipoOferta(tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO +crearIncompatibleCon(incompatibleConVO : IncompatibleConVO) : IncompatibleConVO +existsIncompatibleCon(incompatibleConVO : IncompatibleConVO) : Boolean +borrarIncompatibleCon(incompatibleConVO : IncompatibleConVO) : void +crearTipoOferta(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) : TipoOfertaVO +borrarTipoOferta(idTipoOferta : Long) : void +cambiarTipoOferta(tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO +cambiarTipoOferta(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) : TipoOfertaVO +recuperarTipoOferta(idTipoOferta : Long) : TipoOfertaVO +recuperarTipoOfertas(startIndex : int,count : int) : Collection +recuperarIncompatibleConA(idTipo : Long,startIndex : int,count : int) : Collection +recuperarAplicableA(idTipo : Long,startIndex : int,count : int) : Collection <<realize>> GeneralTipoOfertaFacade -dataSource : DataSource <<create>> +GeneralTipoOfertaFacade() +borrarTipoOferta(idTipoOferta : Long) : void +cambiarTipoOferta(tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO +crearTipoOferta(tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO +crearTipoOferta(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) : TipoOfertaVO +recuperarTipoOferta(idTipoOferta : Long) : TipoOfertaVO +recuperarTipoOfertas(startIndex : int,count : int) : Collection +cambiarTipoOferta(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) : TipoOfertaVO +crearIncompatibleCon(incompatibleConVO : IncompatibleConVO) : IncompatibleConVO +borrarIncompatibleCon(incompatibleConVO : IncompatibleConVO) : void +existsIncompatibleCon(incompatibleConVO : IncompatibleConVO) : Boolean +recuperarIncompatibleConA(idTipo : Long,startIndex : int,count : int) : Collection +recuperarAplicableA(idTipo : Long,startIndex : int,count : int) : Collection actions Figura 6.39: Diagrama Simple de Gesti´n de Tipos de Ofertas o
    • 6.4. Arquitectura del Modelo 152 CambiarTipoOfertaCompletaAction <<create>> +CambiarTipoOfertaCompletaAction(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) -isPetitionCongruent() : boolean +execute(connection : Connection) : Object CrearTipoOfertaCompletaAction <<create>> +CrearTipoOfertaCompletaAction(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) -isPetitionCongruent() : boolean +execute(connection : Connection) : Object CambiarTipoOfertaAction <<create>> +CambiarTipoOfertaAction(tipoOfertaVO : TipoOfertaVO) +execute(connection : Connection) : Object BorrarIncompatibleConAction <<create>> +BorrarIncompatibleConAction(incompatibleConVO : IncompatibleConVO) +execute(connection : Connection) : Object <<interface>> TransactionalPlainAction CrearIncompatibleConAction <<create>> +CrearIncompatibleConAction(incompatibleConVO : IncompatibleConVO) +execute(connection : Connection) : Object CrearTipoOfertaAction <<create>> +CrearTipoOfertaAction(tipoOfertaVO : TipoOfertaVO) +execute(connection : Connection) : Object BorrarTipoOfertaAction <<create>> +BorrarTipoOfertaAction(idTipoOferta : Long) +execute(connection : Connection) : Object <<interface>> PlainAction +execute(connection : Connection) : Object ExistsIncompatibleConAction <<create>> +ExistsIncompatibleConAction(incompatibleConVO : IncompatibleConVO) +execute(connection : Connection) : Object RecuperarAplicableAAction <<create>> +RecuperarAplicableAAction(idTipo : Long,startIndex : int,count : int) +execute(connection : Connection) : Object <<interface>> NonTransactionalPlainAction RecuperarIncompatibleConAAction <<create>> +RecuperarIncompatibleConAAction(idTipo : Long,startIndex : int,count : int) +execute(connection : Connection) : Object RecuperarTipoOfertaAction <<create>> +RecuperarTipoOfertaAction(idTipoOferta : Long) +execute(connection : Connection) : Object RecuperarTipoOfertasAction <<create>> +RecuperarTipoOfertasAction(startIndex : int,count : int) +execute(connection : Connection) : Object Figura 6.40: Actions de Gesti´n de Tipos de Ofertas o
    • 6.4. Arquitectura del Modelo 153 Este Session Facade es el encargado de manejar la creaci´n, recuperaci´n y consulta o o de los tipos de oferta. La interfaz de esta fachada es TipoOfertaFacade y el Business Delegate que la implemente es GeneralTipoOfertaFacade. Al igual que en los Session Facade anteriores, los m´todos de la fachada delegan su funcionamiento en las acciones e del subpaquete Actions que se explicar´n a continuaci´n. a o Las acciones en base a las cual se implementan las operaciones de TipoOfertasFacade, se podr´n clasificar como transaccionales y no transaccionales. Adem´s, a diferencia de a a otros Session Facade, estas acciones son algo m´s complejas, debido a que hay que tener a especial cuidado con que la base de datos de ofertas no quede en un estado inconsistente. En los siguientes puntos se aclara el funcionamiento de cada una de las acciones de esta fachada: CrearTipoOfertaAction Esta acci´n se encarga de crear un nuevo tipo de oferta. o Para ello se le pasan los datos del nuevo tipo de oferta y utilizando los DAOs pertinentes, primero comprueba que el tipo de oferta no existe y luego inserta el nuevo tipo en la base de datos. CrearIncompatibleConAction Esta acci´n ser´ la encargada de crear una ino a compatibilidad entre dos tipos de oferta. Para ello se le pasa un objeto que contiene los identificadores de los dos tipos que son incompatibles. La incompatibilidad es rec´ ıproca, es decir, si A es incompatible con B entonces B tambi´n e es incompatible con A. A continuaci´n se comprueba que la incompatibilidad no existe, en ese caso se o inserta la nueva utilizando IncompatibleConDAO, sino simplemente no se hace nada. CrearTipoOfertaCompletaAction A veces puede que se quiera crear un tipo de oferta, sus incompatibilidades y a qu´ ser´ aplicable, en el mismo momento. e a Esta acci´n da soporte para que eso se pueda realizar. Como se puede adivinar, o en este caso se necesitar´n los datos del tipo de oferta, pero adem´s tambi´n a a e
    • 6.4. Arquitectura del Modelo 154 se necesitar´ un conjunto de todas las incompatibilidades que se deseen crear, a y otro que contenga todos aquellos productos a los que se podr´ aplicar el tipo a de oferta. Primero se comprueba que todos los datos recibidos sean congruentes, por ejemplo, que el identificador del tipo de oferta que se quiere crear sea uno de cada una de las parejas de identificadores del conjunto de incompatibilidades. Una vez realizadas las comprobaciones pertinentes, se chequea si el tipo de oferta ya existe, si es as´ se a˜aden las incompatibilidades y los productos a ı, n los que se aplicar´ (siempre y cuando no est´n ya en la base de datos), sino se a e crea el nuevo tipo y todas sus relaciones. CambiarTipoOfertaAction Esta acci´n permite modificar los datos de un tipo o de oferta. Para eso le hay que pasar los nuevos datos del tipo de oferta. La acci´n, comprueba que el tipo de oferta exista, de ser as´ recupera la inforo ı maci´n antigua, la compara con los nuevos datos y actualiza aquellos que se o han cambiado. CambiarTipoOfertaCompletaAction Al igual que CambiarTipoOfertaAction, permite cambiar los datos de un tipo de oferta, pero en este caso tambi´n se e permitir´ cambiar las incompatibilidades y los productos a los que es aplicable a el tipo de oferta. Del mismo modo que CrearTipoOfertaCompletaAction, esta acci´n recibe los o mismos par´metros y comprueba que la petici´n sea congruente, luego recupera a o los todos datos antiguos y actualiza aquellos que han sido modificados. En el caso de las incompatibilidades, se crean aquellas que no existan, y si alguna de las existente ya no es necesaria, entonces se elimina. BorrarIncompatibleConAction Es la acci´n encargada de eliminar una incomo patibilidad entre tipos de oferta. Para ello se le pasa un objeto VO que contiene los identificadores de los tipos incompatibles que se desean borrar.
    • 6.4. Arquitectura del Modelo 155 La acci´n busca la incompatibilidad en ambos sentidos, A con B y B con A, y o si las encuentra las elimina. BorrarTipoOfertaAction Se encarga de borrar un tipo de oferta. Para realizar esta operaci´n la acci´n simplemente necesita el identificador del tipo de oferta, o o lo busca en la base de datos y todas sus incompatibilidades. Una vez que ha recuperado todos los datos entonces los elimina. ExistsIncompatibleConAction Esta acci´n es la encargada de chequear si existe o una incompatibilidad entre dos tipos de oferta. Para hacer esta comprobaci´n o necesita que se le pase un objeto VO con los dos identificadores que se desean buscar. Devuelve el resultado a trav´s de un objeto ’boolean’. e RecuperarAplicableAAction Se encarga de recuperar todos los productos a los cuales se puede aplicar un tipo de oferta. Para ello le hay que proporcionar el identificador del tipo de oferta. La acci´n busca los datos solicitados y devuelve un objeto ’Collection’ con la o informaci´n requerida. o RecuperarIncompatibleConAAction Se encarga de recuperar todos los tipos de oferta que son incompatibles con el tipo que se indica. Para ello le hay que proporcionar el identificador del tipo de oferta. La acci´n busca los tipos de oferta que son incompatibles con el indicado y o devuelve un objeto ’Collection’ con la informaci´n requerida. o RecuperarTipoOfertaAction Con esta acci´n se permite recuperar los datos de o un tipo de oferta. Para ello se le especifica el identificador del tipo. La acci´n simplemente recupera los datos del tipo de oferta solicitado y los o devuelve a mediante un objeto TipoOfertaVO. RecuperarTipoOfertasAction Esta acci´n se encarga de recuperar todos los tio pos de oferta, desde una posici´n determinada y la cantidad que se solicite. o
    • 6.4. Arquitectura del Modelo 156 Para ello se le indica la posici´n desde la que se desea comenzar a recuperar y o la cantidad de tipos que se quieren. La acci´n recupera todos los tipos requeridos y los devuelve en un objeto ’Coo lleciton’. <<interface>> OfertaFacade +crearOferta(ofertaVO : OfertaVO) : OfertaVO +crearOferta(ofertaVO : OfertaVO,tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Map,colIncompatibleConVO : Collection) : OfertaVO +borrarOferta(idOferta : Long) : void +cambiarOferta(ofertaVO : OfertaVO) : OfertaVO +cambiarOferta(ofertaVO : OfertaVO,tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) : OfertaVO +recuperarOferta(idOferta : Long) : OfertaVO +getOfertaCompleta(idOferta : Long) : OfertaCompletaChunkVO +publicarOferta(idOferta : Long,publicar : Boolean) : void +recuperarOfertasPorTipo(idOferta : Long,startIndex : int,count : int) : Collection +recuperarOfertasActuales(startIndex : int,count : int) : Collection +recuperarOfertasBorradores(startIndex : int,count : int) : Collection +recuperarOfertasPublicadas(startIndex : int,count : int) : Collection +recuperarOfertas(startIndex : int,count : int) : OfertasCollectionChunkVO +CalcularDescuento(dniPasPersona : String,ofertables : Collection) : Collection <<realize>> GeneralOfertaFacade -dataSource : DataSource <<create>> +GeneralOfertaFacade() +CalcularDescuento(dniPasPersona : String,ofertables : Collection) : Collection +borrarOferta(idOferta : Long) : void +cambiarOferta(ofertaVO : OfertaVO) : OfertaVO +crearOferta(ofertaVO : OfertaVO) : OfertaVO +crearOferta(ofertaVO : OfertaVO,tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Map,colIncompatibleConVO : Collection) : OfertaVO +recuperarOferta(idOferta : Long) : OfertaVO +getOfertaCompleta(idOferta : Long) : OfertaCompletaChunkVO +publicarOferta(idOferta : Long,publicar : Boolean) : void +recuperarOfertas(startIndex : int,count : int) : OfertasCollectionChunkVO +recuperarOfertasActuales(startIndex : int,count : int) : Collection +recuperarOfertasBorradores(startIndex : int,count : int) : Collection +recuperarOfertasPorTipo(idTipo : Long,startIndex : int,count : int) : Collection +recuperarOfertasPublicadas(startIndex : int,count : int) : Collection +cambiarOferta(ofertaVO : OfertaVO,tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection) : OfertaVO actions vo <<interface>> OfertaCompletaChunkVO <<realize>> GeneralOfertaCompletaChunkVO OfertasCollectionChunkVO Figura 6.41: Diagrama Simple de Gesti´n de Ofertas o
    • 6.4. Arquitectura del Modelo 157 CrearOfertaCompletaAction <<create>> +CrearOfertaCompletaAction(ofertaVO : OfertaVO,tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Map,colIncompatibleConVO : Collection) -isPetitionCongruent() : boolean -createNecesaryCollections(id : Long) : void +execute(connection : Connection) : Object CrearOfertaAction <<create>> +CrearOfertaAction(ofertaVO : OfertaVO) +execute(connection : Connection) : Object CambiarOfertaAction <<interface>> TransactionalPlainAction <<create>> +CambiarOfertaAction(ofertaVO : OfertaVO) +execute(connection : Connection) : Object BorrarOfertaAction <<create>> +BorrarOfertaAction(idOferta : Long) +execute(connection : Connection) : Object PublicarOfertaAction <<create>> +PublicarOfertaAction(idOferta : Long,publicar : Boolean) +execute(connection : Connection) : Object <<interface>> PlainAction +execute(connection : Connection) : Object CalcularDescuentoAction <<create>> +CalcularDescuentoAction(dniPasPersona : String,ofertableCollection : Collection) +execute(connection : Connection) : Object RecuperarOfertaAction <<create>> +RecuperarOfertaAction(idOferta : Long) +execute(connection : Connection) : Object RecuperarOfertasAction <<create>> +RecuperarOfertasAction(startIndex : int,count : int) +execute(connection : Connection) : Object <<interface>> NonTransactionalPlainAction RecuperarOfertasActualesAction <<create>> +RecuperarOfertasActualesAction(startIndex : int,count : int) +execute(connection : Connection) : Object RecuperarOfertasBorradoresAction <<create>> +RecuperarOfertasBorradoresAction(startIndex : int,count : int) +execute(connection : Connection) : Object RecuperarOfertasPorTipoAction <<create>> +RecuperarOfertasPorTipoAction(idTipo : Long,startIndex : int,count : int) +execute(connection : Connection) : Object RecuperarOfertasPublicadasAction <<create>> +RecuperarOfertasPublicadasAction(startIndex : int,count : int) +execute(connection : Connection) : Object Figura 6.42: Actions de Gesti´n de Ofertas o
    • 6.4. Arquitectura del Modelo 158 La interfaz de este Session Facade es OfertasFacade, implementado por el Business Delegate GeneralOfertasFacade. Al igual que en los Session Facade anteriores, los m´todos e de la fachada delegan su funcionamiento en las acciones del subpaquete Actions que se explicar´n a continuaci´n. a o Para implementar algunas de las acciones de esta fachada hubo que realizar un sistema aparte que se puede ver a grandes rasgos en la figura 6.49 de la secci´n 6.4.5. Este o sistema ser´ el encargado de realizar las operaciones relativas al c´lculo de descuentos a a proporcionados por las ofertas que actualmente est´n en vigor. En la secci´n 6.4.5 se exa o plicar´ en detalle el funcionamiento de este sistema, sus principales tareas, y c´mo est´n a o a implementadas. Esta fachada tambi´n manejar´ unos objetos especiales, los Custom Value Objects. Este e a tipo de objetos, cuyo uso y cometido ya se ha mencionado en la explicaci´n de subsistemas o anteriores, se encontrar´n en el subpaquete ’vo’. Cabe destacar el OfertaCompletaChunka VO ya que no es un Value Object puro, a este VO es una interfaz implementada por GeneralOfertaCompletaChunkVO a la cual no hace falta pasarle todos los atributos al constructor, sino que a partir de los datos de una oferta (OfertaVO) se encarga de acceder a la base de datos mediante los DAO y recuperar las incompatibilidades y dem´s datos a que se encapsulan. Luego proporciona m´todos de lectura y escritura como cualquier Value e Object. Las acciones en base a las cual se implementan las operaciones de HabitacionesFacade, se podr´n clasificar como transaccionales y no transaccionales como ocurr´ en los dem´s a ıa a subsistemas. Estas acciones son las que se comentan a continuaci´n: o CrearOfertaAction Esta acci´n se encarga de crear una nueva oferta. Para ello se o le pasan los datos de la nueva oferta y utilizando los DAOs pertinentes inserta su informaci´n en la base de datos. o CrearOfertaCompletaAction Al igual que la acci´n anterior, se encarga de crear o una nueva oferta, pero en algunas ocasiones ser´ necesario crear la oferta y el a
    • 6.4. Arquitectura del Modelo 159 tipo de oferta en el mismo momento, incluyendo las incompatibilidades del tipo de oferta y los productos a los que se puede aplicar. Para esto necesita que se le pasen los datos de la oferta, la informaci´n del nuevo tipo de oferta, los tipos o con los cuales este es incompatible y los productos a los cuales se podr´ aplicar. a Primero se comprueba que los datos sean congruentes, del mismo modo que se hac´ en CrearTipoOfertaCompletaAction. Luego se insertan todos los datos ıa nuevos en la base de datos, en el caso de que alg´n dato ya exista simplemente u se actualiza su informaci´n. o CambiarOfertaAction Esta acci´n es la encargada de modificar los datos de una o oferta. Para ellos se le pasan los nuevos datos de la oferta. A continuaci´n se buscan los datos antiguos de la oferta y se comparan con la o nueva informaci´n proporcionada, en los casos en que no coincidan se actualizan o en la base de datos. BorrarOfertaAction Se encarga de borrar una oferta. Le hay que proporcionar el identificador de la oferta que se quiere eliminar y mediante los DAO correspondientes se elimina de la base de datos PublicarOfertaAction Se encarga de publicar o dar de baja una oferta. El mecanismo de dar de baja se proporciona por si en alg´n momento se publica u una oferta que va en contra de los intereses del negocio. A esta acci´n hay que o pasarle el identificador de la oferta y un objeto de tipo ’boolean’ indicando si se desea publicar o no la oferta. A trav´s de los DAO necesarios esta acci´n actualiza esta informaci´n en la e o o base de datos. CalcularDescuentoAction Es la encargada de, a partir de un conjunto de productos, calcular el mejor descuento que puedan proporcionar las ofertas que se puedan aplicar a esos productos.
    • 6.4. Arquitectura del Modelo 160 Para dar soporte a esta acci´n y al proceso que debe realizar se define una o interfaz que deben implementar todos aquellos productos a los que se les pueda hacer alg´n tipo de descuento. Esta interfaz es la interfaz Ofertable, se puede u ver en la figura 6.43 y otra que a partir de un conjunto de objetos Ofertable los divide en subconjuntos seg´n el tipo de producto que definan, esta es la interfaz u OfertableCollectionChunkVO tambi´n presente en la figura 6.43 e <<interface>> OfertableCollectionChunkVO +getDescuento() : double +setDescuento(descuento : double) : void +getTipoOfertable() : String +getCantidad() : double +extractOfertableCollection() : Collection +acumulateDiscount(discount : Double) : void <<interface>> Ofertable <<realize>> GeneralOfertableCollectionChunkVO -collectionDeT : Collection -tipoOfertable : String -descuento : double -cantidad : double 0..* <<create>> +GeneralOfertableCollectionChunkVO(c : Collection,muestra : Ofertable) +getDescuento() : double +getTipoOfertable() : String +setDescuento(descuento : double) : void +getCantidad() : double +extractOfertableCollection() : Collection +acumulateDiscount(discount : Double) : void 1 +getTipo() : String +getSubTipo() : String +getDescuento() : double +setDescuento(descuento : double) : void +getImporte() : double +getWrapped() : Object +getQuantity() : double +getDayBegin() : int +getMonthBegin() : int +getYearBegin() : int +getDayEnd() : int +getMonthEnd() : int +getYearEnd() : int +getDateBegin() : Calendar +getDateEnd() : Calendar Figura 6.43: Diagrama de la Interfaz Ofertable Esta acci´n necesita recibir el DNI o Pasaporte del cliente para el que se destina o el c´lculo del descuento, y un conjunto de objetos Ofertable que definan todos a los objetos sobre los cuales se har´n los c´lculos para el descuento. a a Una vez se tienen todos estos datos, se delega la operaci´n en el m´todo ’Calo e cularMejorPara’ del calculador de ofertas definido en el sistema de ofertas. El funcionamiento de este sistema se muestra en detalle en la secci´n 6.4.5 o RecuperarOfertaAction Se encarga de recuperar los datos de una oferta. Se le debe pasar el identificador de la oferta. A continuaci´n la acci´n recupera los datos de la oferta solicitada y los devuelve, o o en caso de que la oferta que se pida no exista se lanza una excepci´n. o
    • 6.4. Arquitectura del Modelo 161 RecuperarOfertasAction Esta acci´n es la encargada de recuperar una lista de o todas las ofertas. Para llevar a cabo esta acci´n, necesita que le pasen desde o d´nde se quiere recuperar y la cantidad de ofertas que se desean. o Luego la acci´n, a trav´s de los DAO correspondientes, recoge las ofertas solicio e tadas y las devuelve encapsuladas en un Custom Value Object preparado para realizar paginaci´n. o RecuperarOfertasActualesAction Con esta acci´n se permite recuperar una liso ta de las ofertas que se aplican actualmente. Para ello necesita que se le pase desde d´nde se quieren recuperar las ofertas y la cantidad. o A continuaci´n la acci´n recupera los datos a trav´s de los DAOs y los encapsula o o e en un Custom Value Object, de esta forma, como ya se ha visto, se consigue una paginaci´n de los resultados. o RecuperarOfertasBorradoresAction Esta acci´n permite recuperar una lista o de las ofertas que a´n est´n como borradores. Para ello necesita que se le pase u a desde d´nde se quieren recuperar las ofertas y la cantidad. o A continuaci´n la acci´n recupera los datos a trav´s de los DAOs y los encapsula o o e en un Custom Value Object, para conseguir una paginaci´n de los resultados. o RecuperarOfertasPublicadasAction Permite recuperar una lista de las ofertas que a´n est´n actualmente publicadas. Para ello necesita que se le pase desde u a d´nde se quieren recuperar las ofertas y la cantidad. o A continuaci´n la acci´n recupera los datos a trav´s de los DAOs y los encapsula o o e en un Custom Value Object, para conseguir una paginaci´n de los resultados. o RecuperarOfertasPorTipoAction Esta acci´n se encarga de recuperar todas las o ofertas de un mismo tipo de oferta. Para realizarlo necesita que se le pase desde d´nde se quieren recuperar las ofertas y la cantidad. o Luego se recuperan los datos de las ofertas del tipo solicitado y se devuelven encapsuladas en un Custom Value Object, para que puedan ser paginados.
    • 6.4. Arquitectura del Modelo 6.4.4.5. 162 Gesti´n de Facturas o En esta secci´n se mostrar´ c´mo es el desarrollo de los casos de uso de Gesti´n de o a o o Facturas. Como en los casos anteriores se utiliza el patr´n Session Facade y Business o Delegate para implementar este subsistema. Entre las operaciones de este sistema cabe destacar que debe permitir consultar un borrador de una factura antes de pagarla; pagar una factura en dos pasos, uno para marcar la factura como en proceso de pago y otro para marcarla como pagada; tambi´n e ofrecer´ una operaci´n para cancelar una reserva, calculando el recargo de tal operaci´n a o o si la factura ya estaba pagada. De aqu´ en adelante se mostrar´ c´mo se organizan las clases que forman este subsistema ı a o y luego se aclarar´ el cometido que tiene cada una de ellas. En las figuras 6.44 y 6.45 se a muestra unos diagramas sencillos de la Gesti´n de Facturas. o <<interface>> FacturasFacade +calculateBillDraft(idBill : Long) : FacturaVO +getBillsBetweenDates(fechaInicio : Calendar,fechaFin : Calendar,startIndex : int,count : int) : Collection +getBill(idFactura : Long,startIndex : int,count : int) : FacturaCompletaChunkVO +payBill(codFactura : Long) : void +paymentConfirmation(codFactura : Long) : void +setBillAsPayed(codFactura : Long) : void +getImporteADevolverCancelacion(codReserva : Long) : void +cancelarReserva(codReserva : Long) : double <<realize>> GeneralFacturasFacade -dataSource : DataSource <<create>> +GeneralFacturasFacade() +calculateBillDraft(idBill : Long) : FacturaVO +getBill(idFactura : Long,indexProd : int,count : int) : FacturaCompletaChunkVO +getBillsBetweenDates(fechaInicio : Calendar,fechaFin : Calendar,startIndex : int,count : int) : Collection +payBill(codBill : Long) : void +paymentConfirmation(codBill : Long) : void +setBillAsPayed(codBill : Long) : void +getImporteADevolverCancelacion(codReserva : Long) : void +cancelarReserva(codReserva : Long) : double actions vo exceptions FacturaCompletaChunkVO Figura 6.44: Diagrama Simple de Gesti´n de Facturas o
    • 6.4. Arquitectura del Modelo 163 CalcularBorradorFacturaAction <<create>> +CalcularBorradorFacturaAction(idFactura : Long) +execute(connection : Connection) : Object CancelarReservaAction <<create>> +CancelarReservaAction(codReserva : Long) +execute(connection : Connection) : Object -calculaDevolucionDe(c : Connection,linea : LineaDeReservaVO) : double <<interface>> TransactionalPlainAction PaymentConfirmationAction <<create>> +PaymentConfirmationAction(codBill : Long) +execute(connection : Connection) : Object SetBillAsPayedAction <<interface>> PlainAction +execute(connection : Connection) : Object <<create>> +SetBillAsPayedAction(codBill : Long) +execute(connection : Connection) : Object PayBillAction <<create>> +PayBillAction(codBill : Long) +execute(connection : Connection) : Object GetImporteADevolverCancelacionAction <<interface>> NonTransactionalPlainAction <<create>> +GetImporteADevolverCancelacionAction(codReserva : Long) +execute(connection : Connection) : Object -calculaDevolucionDe(c : Connection,linea : LineaDeReservaVO) : double GetFacturaAction <<create>> +GetFacturaAction(idFactura : Long,startIndex : int,count : int) +execute(connection : Connection) : Object GetFacturasEntreFechasAction <<create>> +GetFacturasEntreFechasAction(fechaInicio : Calendar,fechaFin : Calendar,startIndex : int,count : int) +execute(connection : Connection) : Object Figura 6.45: Actions y Exceptions de Gesti´n de Facturas o En estos diagramas se puede ver c´mo se vuelven a usar los patrones Session Facade o y Business Delegate. La interfaz para acceder a este subsistema es FacturasFacade, implementado por GeneralFacturasFacade. Al igual que en el Session Facade anterior, los m´todos de la fachada delegan su funcionamiento en las acciones correspondientes del e subpaquete Actions. A continuaci´n se explicar´ el funcionamiento de cada una de las o a acciones. Adem´s de usar unas acciones para implementar sus m´todos, esta fachada tambi´n a e e lanza CustomException para proporcionar informaci´n a las capas superiores acerca del o estado con el que finaliz´ la operaci´n. En este caso se usar´n excepciones para informar o o a si se ha podido realizar correctamente el pago de una factura y si se ha podido cancelar una reserva.
    • 6.4. Arquitectura del Modelo 164 Por otro lado, esta fachada manejar´ un objeto especiale, un Custom Value Object. a Estes objeto estar´ localizado en el subpaquete ’vo’ y tendr´n como cometido ofrecer a las a a capas superiores un conjunto de los atributos de varios VO ya existentes. En este caso se usar´ para encapsular una factura y todas sus l´ a ıneas de reserva. Las acciones en base a las cuales se implementan las operaciones de FacturasFacade, tambi´n podr´n clasificarse como transaccionales y no transaccionales dependiendo si es e a necesario que la operaci´n se realice de forma at´mica o no, y son las siguientes: o o CalcularBorradorFacturaAction Esta acci´n es la encargada de calcular el imo porte final que se debe pagar en una factura, teniendo en cuenta los descuentos que puedan proporcionar las ofertas. Para esto necesita que se le pase el identificador de la factura que se desea procesar. A continuaci´n la acci´n recupera todas las l´ o o ıneas de reserva, y ayud´ndose de a las operaciones que proporciona el objeto OfertableCollectionChunkVO divide el conjunto de l´ ıneas recuperadas en varios seg´n el tipo de producto reservado u en cada l´ ınea. Luego utilizando el CalculadorDeOferta del Sistema de Ofertas (se comentar´ en detalle en la secci´n 6.4.5) calcula las mejores ofertas que se podr´n a o a aplicar al conjunto de l´ ıneas de reserva. Luego aplica las ofertas y devuelve un objeto con los datos de la factura actualizados. CancelarReservaAction Esta acci´n permite cancelar una reserva. Para ello se le o debe pasar el c´digo de la reserva que se quiere cancelar. o Luego se recuperan todas las l´ ıneas de reserva de la reserva que se quiere cancelar y se marcan como canceladas. A continuaci´n se actualizan los totales de o la factura en caso necesario y se termina. PayBillAction Se encarga de marcar una factura como en proceso de pago. Para ello necesita que se le pase el identificador de la factura que se va a pagar.
    • 6.4. Arquitectura del Modelo 165 A continuaci´n se marca la factura como que ya no es un borrador, si la factura o ya estaba pagada, en proceso de pago o cancelada, se lanza una excepci´n o indic´ndolo. a PaymentConfirmationAction Se encarga de marcar una factura como pagada definitivamente, es el segundo de los dos pasos necesarios para realizar el pago on-line. Para ello, la acci´n, necesita que le pasen el identificador de la factura. o Luego se actualizan los datos de la factura indicando que ya est´ pagada. a SetBillAsPayedAction Esta acci´n es la encargada marcar una factura como pao gada directamente, este proceso de pago de un solo paso es necesario para cuando el pago se realiza directamente en el establecimiento. Se necesita el identificador de la factura para realizar la operaci´n. o La acci´n actualiza la informaci´n de la factura y marc´ndola como pagada y o o a que ya no es borrador. GetImporteADevolverCancelacionAction Esta acci´n es la encargada de calo cular el importe que hay que devolver en caso de que se cancele una reserva ya pagada. Necesita que se le indique el identificador de la reserva que se quiere cancelar. Luego la acci´n recupera todas las l´ o ıneas de reserva de esa reserva y seg´n los u d´ que resten para que la reserva se haga efectiva se devuelve un porcentaje ıas del importe u otro. Para finalizar se actualizan los datos de las l´ ıneas de reserva y la factura. GetFacturaAction Esta acci´n es la encargada de recuperar los datos de una o factura. Para ello necesita el identificador de la factura que se desea. A continuaci´n se recuperan los datos de la factura y las l´ o ıneas de reserva que la componen y se devuelven encapsulados en un Custom Value Object. GetFacturasEntreFechasAction Esta acci´n es la encargada de recuperar los o datos de todas las facturas pagadas entre dos fechas. Para ello necesitan: la
    • 6.4. Arquitectura del Modelo 166 fecha m´s temprana y la m´s tard´ entre las cuales se desean recupera las a a ıa facturas. A continuaci´n se recuperan los datos de las facturas mediante los DAO y o devuelven a trav´s de un objeto Collection. e 6.4.5. 6.4.5.1. Sistema de Soporte - Modelo de Ofertas Requisitos del Sistema de Ofertas El sistema de Ofertas es un sistema de soporte, totalmente independiente del resto de la aplicaci´n. Este modelo proporcionar´ una serie de funcionalidades, todas ellas relacioo a nadas con las ofertas. En el caso del software que se est´ desarrollando, se pide que las ofertas cumplan unos a requisitos que no son triviales de implementar, por esa raz´n se concluy´ que la mejor o o soluci´n ser´ desarrollar un sistema que funcionara de manera independiente. De esta o ıa forma, si en el futuro se desea cambiar el comportamiento de las ofertas en el negocio para el que se destina la aplicaci´n, unicamente habr´ que modificar este sistema. Antes de o ´ ıa detallar c´mo se dise˜o el sistema, se explicar´ brevemente los requisitos que este tiene o n´ a que cumplir, y c´mo se deben organizar las diferentes ofertas unas con otras. o Todas las ofertas estar´n asociadas a un tipo de oferta, este tipo es el primero que se a va a definir. Cada tipo de oferta especifica entre otras cosas a qu´ tipo de productos del e negocio est´ destinado y cu´l es la cantidad m´ a a ınima necesaria de esos productos para que una oferta de este tipo se pueda aplicar. Adem´s, como las ofertas deben poder ser a acumulables, hay que definir unas incompatibilidades de unos tipos de oferta con otros, de esta forma s´lo se podr´n aplicar conjuntamente aquellas ofertas que sean de tipos o a compatibles todos entre s´ este es uno de los problemas a los que habr´ que hacer frente ı, a en el dise˜o de este sistema. n
    • 6.4. Arquitectura del Modelo 167 Por otro lado, todas las ofertas de un mismo tipo ser´n incompatibles por definici´n, y a o cada oferta tiene que poder definir una regla, mediante la cual, en un contexto determinado (cliente, reserva, fecha, etc) se pueda decidir autom´ticamente si la oferta se puede aplicar a en una factura o no. La definici´n del lenguaje de reglas necesario para dar soluci´n a esta o o necesidad es el segundo de los problemas que debe resolverse con este sistema. Soluci´n al Problema de las Incompatibilidades o Como todas las ofertas de un mismo tipo son incompatibles, para elegir la mejor de todas simplemente se eligir´ la que proporcione un mayor descuento de entre las que a se puedan aplicar. Y para luego conseguir encontrar el conjunto de ofertas compatibles que produzcan el mayor descuento hay que combinar la mejor oferta de cada tipo, con todas las dem´s de los otros tipos, siempre y cuando los tipos de oferta no sean incompatibles. a Para resolver la incompatibilidad entre los distintos tipos, se ide´ constuir un grafo o de incompatibilidades donde los nodos representan los tipos y los arcos indican que dos tipos son incompatibles. Para poner un ejemplo de c´mo se resuelve este problema mediante un grafo, se o tomar´n 5 tipos de oferta, A, B, C, D y E. El tipo de oferta E ser´ incompatible con a a el A, el B y el C; y el tipo B con el C. As´ se muestra en el siguiente grafo. ı A B D C E Grafo ’g’ - Ejemplo de Incompatibilidades
    • 6.4. Arquitectura del Modelo 168 Una vez observado el grafo en el que se expresan las incompatibilidades hay que darle soluci´n, y conseguir deducir todos aquellos conjuntos de ofertas que son compatibles o entre s´ ı. Como un estudio puramente matem´tico llevar´ mucho tiempo, se buscar´ una a ıa a forma pr´ctica de resolverlo. Para ello se intentar´ buscar una serie de pasos con los a a cuales se puedan ir obteniendo aproximaciones de la soluci´n que se busca. o Una primera aproximaci´n podr´ ser, dado que se tiene un grafo de incompatibilio ıa dades, crear el grafo de compatibilidades correspondiente. Pero esto tendr´ un serio ıa coste computacional si aumentasen las ofertas (nodos) del grafo. Teniendo esto en cuenta, y utilizando algo de notaci´n matem´tica, se puede calcular una matriz de o a adyacencia del grafo de incompatibilidades identificando la presencia de una relaci´n o de incompatibilidad mediante un ’1’ y la ausencia de la misma con un ’0’, de esta forma se puede ver muy f´cilmente y de manera compacta con qu´ otras ofertas a e es compatible una dada, simplemente identificando los ’0’ de una fila de la matriz. Los nombres que se dar´n a las filas y columnas de la matriz de adyacencia ser´n: a a ’A’, ’B’, ’C’, ’D’ y ’E’; en orden de izquierda a derecha y de arriba abajo. Dando como resultado, como matriz de adyacencia asociada al grafo del ejemplo anterior, la siguiente:  0 0 0 0 1   0   Ady(g) = 0    0  1    0 1 0 1   1 0 0 1    0 0 0 0  1 1 0 0 De la matriz Ady(g) se puede sacar f´cilmente el grafo de compatibilidades, ya que a en ese caso las relaciones de compatibilidad ser´ las representadas por los ’0’. Con ıan esta simple matriz ya se puede saber qu´ ofertas son compatibles y con cu´les, pero e a a´n falta algo, se ve claramente con el siguiente ejemplo: con los datos de la matriz se u
    • 6.4. Arquitectura del Modelo 169 llega a la conclusi´n de que ’A’ es compatible con ’A’, ’B’, ’C’ y ’D’, pero lo que no se o puede saber directamente es que todas ellas, los ’0’ de la fila, sean compatibles entre s´ en este caso ’B’ y ’C’ no son compatibles y no se podr´ aplicar conjuntamente. ı, ıan ¿C´mo solucionarlo?, lo que se necesita es calcular conjuntos de ofertas que s´ sean o ı compatibles entre s´ y se sabe que la fila ’N’ es compatible con los ’0’ de su fila, por lo ı, tanto se puede realizar una ’criba’. Cambiando los ’0’ por ’1’, es decir, con la matriz complementaria a Ady(g), se pueden realizar ’AND’ l´gicos de cada una de las filas o con las filas de cada uno de sus componentes con los que es compatible, o como se ver´ a continuaci´n, utilizando conjuntos y haciendo intersecciones de los conjuntos a o compatibles, dando como resultado un conjunto de ofertas todas compatibles entre s´ ı. Se puede observar mucho m´s f´cilmente resolviendo el ejemplo con el que se est´ traa a a bajando. Primero se realiza el c´lculo de Ady(¯), la matriz complementaria a Ady(g). a g  1   1   Ady(¯) = 1 g    1  0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 1  0   0   0    1  1 A partir de la informaci´n de esta matriz, se comienza identificando el conjunto de o ofertas que son compatibles con ’A’, las que lo son con ’B’, etc. Estos conjuntos se identificar´n como C(A), C(B), C(C), C(D) y C(E), y a los conjuntos resultantes de a ofertas compatibles entre s´ se les llamar´ R(A), R(B), R(C), R(D) y R(E). En el ı a ejemplo con el que se est´ trabajando se tienen los siquientes conjuntos: a C(A) = {A, B, C, D} C(B) = {A, B, D} C(C) = {A, C, D}
    • 6.4. Arquitectura del Modelo 170 C(D) = {A, B, C, D, E} C(E) = {D, E} Y para calcular los conjuntos de ofertas que son compatibles entre si, se hace la intersecci´n de cada uno de los conjuntos con los conjuntos de las ofertas con las que o es compatible. A continuaci´n se muestran estas intersecciones y los resultados: o R(A) = C(A) ∩ C(B) ∩ C(C) ∩ C(D) = {A, D} R(B) = C(A) ∩ C(B) ∩ C(D) = {A, B, D} R(C) = C(A) ∩ C(C) ∩ C(D) = {A, C, D} R(D) = C(A) ∩ C(B) ∩ C(C) ∩ C(D) ∩ C(E) = {D} R(D) = C(D) ∩ C(E) = {D, E} Las ofertas de estos cinco conjuntos que se acaban de calcular, son compatibles entre s´ por lo que se podr´ aplicar sus descuentos conjuntamente en una factura. Una vez ı, ıa resuelto este problema, el sistema deber´ escoger el conjunto que ofrece un mayor a descuento sobre el importe de la factura, esta operaci´n se realiza calculando el o descuento que ofrece cada uno de los conjuntos y escogiendo el que ofrezca el mayor de todos. Soluci´n al Problema de las Reglas para las Ofertas o Como ya se ha mencionado, el sistema debe proporcionar la mayor flexibilidad posible para que las ofertas definan su ´mbito de aplicaci´n. Para realizarlo se debe a o implementar un sistema mediante el cual cada oferta pueda chequear cuando lo necesite si se puede, o no, aplicar en un contexto determinado. Para comenzar har´ falta guardar la regla junto con los datos de la oferta en la base a de datos, esta se almacenar´ de forma textual. a
    • 6.4. Arquitectura del Modelo 171 Una regla ser´ una cadena de caracteres, entre los cuales se intercalar´n caracteres a a especiales para indicar las diferentes partes y funcionalidades que tendr´n las dem´s a a subcadenas. Esto es lo primero que hay que hacer, definir una sintaxis que se utilizar´ en la construcci´n de las distintas reglas. Adem´s, para que una regla se pueda a o a adaptar f´cilmente a la situaci´n en la que se va a aplicar, se tienen que proporcioa o nar suficientes formas de moldear como se quiera el contexto necesario para que se aplique una oferta, y dar la posibilidad de, en el momento que se necesite, poder ampliar este sistema para proporcionar otras formas de medici´n distintas. En otras o palabras, con una regla se tendr´n que poder definir cosas como: la fecha a partir de a la cual habr´ que hacer una reserva para que se aplique la oferta, la edad m´ ıa ınima del cliente, la edad m´xima, el pa´ de origen, etc. Y poder proporcionar en el futuro a ıs formas de definir otros aspectos contra los cuales se pueda cotejar la aplicaci´n de o una oferta. Para dar cabida a definir todos estos aspectos y posibilitar la definici´n de m´s, o a se ve necesario que una regla se divida en partes bien diferenciadas donde cada parte definir´ una unica situaci´n y para que una regla se cumpla, se deben cumplir a ´ o todas las partes. Cada una de las partes tendr´ un identificador (nombre) y unos a par´metros que necesitar´ para chequearse, por ejemplo, a la parte de regla que debe a a comprobar la edad de un cliente se le tiene que proporcionar por ejemplo una fecha de nacimiento para que la tome como referencia. Los caracteres que se utilizar´n para separar las diferentes partes de la regla ser´n a a ’&&’. Luego har´ falta diferenciar el identificador de cada parte de sus par´metros, a a para eso se utilizar´ ’:’ y dentro de la zona de los argumentos hay que diferenciar a cada uno de ellos, para lo que se har´ uso del caracter ’,’. Un ejemplo de c´mo quea o dar´ una regla es el siguiente: ıa PersonBornBefore:30,8,1987&&PersonFrom:Espa˜a n
    • 6.4. Arquitectura del Modelo 172 El ejemplo de regla anterior permitir´ que la oferta se aplicase si el cliente al que ıa va destinada naci´ antes del 30 de Agosto de 1987 y s´lo si tiene su domicilio en o o Espa˜a. Podr´ suceder tambi´n que hubiese una parte de la regla sin argumentos o n ıa e que la regla no tubiese ninguna parte. 6.4.5.2. Dise˜ o e Implementaci´n del Sistema de Ofertas n o A diferencia de c´mo se han explicado los subsistemas anteriores, en este caso se comeno zar´ describiendo las funcionalidades que ofrecen las clases m´s importantes del sistema. a a Se recorrer´ este modelo dividi´ndolo en subconjuntos de clases que proporcionen funcioa e nalidades necesarias para el resto de la aplicaci´n. o En primer lugar se describir´n las clases necesarias para dar soporte al sistema de a las reglas para las ofertas y como se relacionan entre s´ La mejor forma de ver c´mo ı. o interact´an diferentes clases es a trav´s de un diagrama, as´ lo podremos observar en la u e ı figura 6.46.
    • 6.4. Arquitectura del Modelo 173 RulePartFactory Rule -availableRuleParts : Collection -availableRulePartsFile : String -ruleParts : Collection <<call>> +getValidRuleParts() : Collection +getRulePart(key : String,args : String[]) : RulePart +getRulePart(key : String) : RulePart +existsRulePart(key : String) : boolean <<create>> +Rule(s : String) -getKey(s : String) : String -getArgs(s : String) : String[] +isOfferApplicable(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isRuleCorrectlyFormed(s : String) : boolean 0..* 1 <<interface>> RulePart +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean AlwaysTrue <<create>> +AlwaysTrue() +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean PersonBornAfter -day : Integer -month : Integer -year : Integer <<create>> +PersonBornAfter() +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean PersonBornBefore -day : Integer -month : Integer -year : Integer <<create>> +PersonBornBefore() +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean PersonFrom -country : String <<create>> +PersonFrom() +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean ReservationDoneBefore -day : Integer -month : Integer -year : Integer <<create>> +ReservationDoneBefore() +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean Figura 6.46: Diagrama del Sistema de Reglas
    • 6.4. Arquitectura del Modelo 174 La clase regla es la encargada de crear din´micamente una regla y ofrece m´todos de a e comprobaci´n para saber si su aplicaci´n a un conjunto de productos ofertables, una o o persona, etc, result´ exitosa o no, y de chequeo para saber si la cadena y todas sus partes o est´n bien formadas. En realidad la regla no realiza estas comprobaciones, sin´ que delega a o su funcionamiento en las distintas partes de regla que la componen. El unico cometido de ´ esta clase es chequear la cadena que forma la regla, dividirla e identificar sus componentes para crear los objetos RuleParts oportunos ayud´ndose de la clase RulePartFactory, la a cual se encarga de, a partir de un nombre identificativo crear un objeto RulePart. Para saber qu´ tipo de objeto implementa cada uno de los RuleParts solicitados, hace uso de la e clase de utilidad ConfigurationParametersManager. En el cap´ ıtulo 7, en el apartado 7.3.0.1 se podr´ observar c´mo se realiz´ la implementaci´n de los m´todos m´s importantes de a o o o e a esta clase. Actualmente se proporcionan definidos en el sistema cinco tipos distintos de objetos RulePart, pero a˜adir nuevas partes para las reglas ser´ tan sencillo como crear un nuevo n ıa objeto que implemente la interfaz RulePart y especificar su nombre y nombre de clase en un fichero para que est´ localizable; a partir de ese momento ya se puede utilizar en la e aplicaci´n sin ning´n problema. o u Los tipos definidos son los siguientes: AlwaysTrue Esta parte de regla no necesita de ning´n par´metro, cuando se utiliza u a es para indicar que siempre es verdad, no tiene mucha utilidad a no ser que el administrador a la hora de crear una oferta quiera estar seguro de que se aplique siempre, en ese caso utilizar´ esta parte de regla. ıa PersonBornAfter En este caso, esta parte de regla necesita tres argumentos para indicarle una fecha (d´ mes y a˜o). En un primer lugar se comprueba que ıa, n la fecha est´ correctamente formada, y cuando se pide que se compruebe si se e cumple, lo que hace esta parte de regla es chequear si el cliente del contexto
    • 6.4. Arquitectura del Modelo 175 actual tiene como fecha de nacimiento una posterior a la indicada mediante los par´metros. a PersonBornBefore Esta parte de regla necesita tres argumentos igual que la anterior para indicarle una fecha (d´ mes y a˜o). Realiza las mismas comprobaıa, n ciones que PersonBornAfter pero esta vez chequea que el cliente naciera antes de la fecha indicada. Esta es la clase escogida como ejemplo para ilustrar c´mo o se debe crear un nuevo objeto RulePart. PersonFrom En este caso se necesita un unico argumento para indicar el nombre ´ de un pa´ Primero se comprueba que se le pasa este argumento y luego debe ıs. chequear que el cliente contra el que se debe validar la regla sea del pa´ indicado. ıs ReservationDoneBefore Esta parte de regla se encarga de comprobar que la reserva se haga antes de una fecha, para ello necesita tres par´metros para indicar a la fecha l´ ımite que se desea establecer, luego se comprueba que la fecha sea correcta y que la reserva se est´ haciendo en realidad antes del d´ especificado. e ıa Para dar implementaci´n a una nueva parte de regla lo unico que hay que hacer es o ´ definir el comportamiento necesario de los m´todos indicados en la interfaz RulePart. e En el cap´ ıtulo 7 en la secci´n 7.3.0.3 se muestra la implementaci´n de la parte de regla o o ’PersonBornBefore’, cualquier otra implementaci´n de otra parte de regla que se quisiese o realizar ser´ an´loga a esa. ıa a Una vez creada la nueva parte de regla hay que a˜adir una nueva entrada en el fichero de n configuraci´n ConfigurationParameters.properties para indicar d´nde se puede localizar la o o nueva clase. Adem´s de las reglas, el sistema de ofertas necesitaba calcular el mejor conjunto de a ofertas compatibles que se pod´ aplicar a los productos de una factura. En la secci´n ıan o anterior se desarroll´ un algoritmo pr´ctico para dar soluci´n a este problema, este algoo a o ritmo lo implementa una clase particular en el sistema, esta es, BestSetOfOffers, la cual, a
    • 6.4. Arquitectura del Modelo 176 partir de los nodos del grafo (las ofertas) y los descuentos que estas proporcionan sobre la colecci´n de productos ofertables, calcula cu´l es el mejor conjunto de ofertas compatibles o a entre s´ ı. En primer lugar rellena una matriz cuyas filas y columnas son los identificadores de las ofertas y borra aquellos elementos en donde fila y columna son incompatibles. Esta es la primera criba que debe pasar la matriz, pero no la unica, porque, como ya se ha visto, ´ dentro de los elementos de una fila puede haber algunos que sean incompatibles entre s´ ı, por eso se realiza una segunda criba para eliminar aquellos que dentro de una misma fila son incompatibles. Una vez terminado este proceso, los elementos restantes dentro de cada una de las filas de la matriz son todos compatibles, por lo que ahora s´lo resta comprobar cu´nto es el o a descuento que se puede acumular con cada una de las filas (que son las que forman los conjuntos de ofertas compatibles) y aquel conjunto que proporcione el mayor importe a descontar ser´ el buscado. a BestSetOfOffers -nodes : Map -relations : Collection -bestSetOfOffersIds : ArrayList -bestDiscount : Double <<create>> +BestSetOfOffers(nodes : Map) +getBestSetOfOffersIds() : ArrayList +getBestDiscount() : Double -getAllIncompatibleWith() : void Figura 6.47: Diagrama de clase BestSetOfOffers
    • 6.4. Arquitectura del Modelo 177 Para las expecativas que hab´ sobre esta soluci´n, decir que, finalmente, es lo suficienteıa o mente r´pida y eficaz para satisfacerlas. A´n as´ si lo que se quiere es rapidez a la hora de a u ı, realizar c´lculos, se debe intentar que el c´lculo del conjunto de mejores ofertas se haga el a a m´ ınimo n´mero de veces posible. Como esta operaci´n s´lo ser´ estrictamente necesaria u o o ıa a la hora de realizar el pago de una factura, es en el momento de comprobar una factura antes de pagarla cuando se ha utilizado esta funcionalidad en la aplicaci´n final. o Una vez visto el funcionamiento de las clases necesarias para dar soporte al sistema de reglas y para calcular el mejor conjunto de ofertas, se mostrar´ la clase que funciona como a interfaz para las capas superiores, abstrayendo todo el funcionamiento que se ha explicado. Esta clase es ‘CalculadorImpl‘ que implementa la interfaz ‘Calculador‘. La clase CalculadorImpl es la encargada de realizar el c´lculo del mejor conjunto de ofertas aplicables a un a conjunto de productos ‘Ofertable‘, haciendo uso de ‘BestSetOfOffers‘ para dicho c´lculo. a En un nivel superior se encuentra la clase ‘GeneralCalculadorDeOferta‘ que es el encargado de pasar a CalculadorImpl los datos necesarios para que este devuelva el resultado deseado, para filtrar los datos que se pasan a CalculadorImpl, GeneralCalculadorDeOferta hace uso de todo el sistema de reglas para comprobar que todas las ofertas que se van a pasar se puedan aplicar. Utilizando estas dos clases se consigue separar la decisi´n de si o una oferta se puede aplicar o no, del c´lculo del mejor conjunto de ofertas. Se utiliza para a esto el proceso denominado ‘delegaci´n‘ a trav´s del cual, GeneralCalculadorDeOferta reao e liza las operaciones que le corresponden y delega en CalculadorImpl el c´lculo del mejor a conjunto de ofertas. De este modo, el d´ de ma˜ana se podr´ cambiar, si se quisiese, la ıa n ıa implementaci´n de ‘Calculador‘ para que sea m´s eficiente. o a A continuaci´n se muestran los m´todos que ofrecen estas dos clases en la figura 6.48 o e
    • 6.4. Arquitectura del Modelo 178 <<interface>> CalculadorDeOferta +CalcularMejorPara(c : Connection,colOfertable : Collection,dniPasPersona : String) : Collection +setCalculador(c : Calculador) : void +getAppliedOffers() : Collection GeneralCalculadorDeOferta -colDeCol : Collection -calculador : Calculador -colOfApplied : Collection -split(colOfertable : Collection) : void +setCalculador(c : Calculador) : void -canBeApplied(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +CalcularMejorPara(c : Connection,colOfertable : Collection,dniPasPersona : String) : Collection +getAppliedOffers() : Collection 1 1 <<interface>> Calculador +calculaMejorOferta(colProductos : Collection,colOfertasPosibles : Collection) : Collection +getAppliedOffers() : Collection CalculadorImpl -myProxyMap : Map -myBestSetOfOffersTypes : Collection -myFinalOfertableCol : Collection +calculaMejorOferta(colProductos : Collection,colOfertasPosibles : Collection) : Collection -getBestOffer(colOf : Collection) : OfertaVO -getAmountDiscounted(colProductos : Collection,offer : OfertaVO) : Double -acumularOfertaEnOfertableCollection(colProductos : Collection,offer : OfertaVO) : void -calcAmount(col : Collection,discountTemp : Double) : Double +getAppliedOffers() : Collection Figura 6.48: Diagrama de las Clases Calculadoras
    • 6.4. Arquitectura del Modelo 179 De la clase GeneralCalculadorDeOferta se podr´ destacar el m´todo ‘calcularMejorPara‘ ıa e encargado de calcular el mejor descuento para un conjunto de objetos ‘Ofertable‘. El primer paso a realizar es dividir el conjunto de objetos Ofertable inicial en un conjunto de conjuntos divididos seg´n el tipo de Ofertable, a continuaci´n se recuperan todas las u o ofertas y ayud´ndose del sistema de reglas, se escogen simplemente aquellas que seg´n su a u regla se puedan aplicar. Una vez que se tienen estos datos, se delega el resto del c´lculo a en el m´todo ‘calculaMejorOferta‘ del objeto ‘Calculador‘. e Otro m´todo importante es ‘calculaMejorOferta‘ de la clase CalculadorImpl, encargado e de, utilizando BestSetOfOffers, calcular el mejor descuento para el conjunto de conjuntos de objetos Ofertable recibido a partir de las ofertas que le pasan. En primer lugar divide las ofertas por tipos y escoge la que proporciona el mayor descuento de cada tipo, ya que de cada tipo solo se podr´ aplicar una oferta. A continuaci´n se calcula el descuento que a o proporciona cada una de las ofertas elegidas, y se le pasa esta informaci´n a BestSetOfOfo fers para que calcule el conjunto de ofertas compatibles que ofrezca un mayor descuento, para luego calcular el total que proporcionan de descuento sobre el conjunto de Ofertables. En el cap´ ıtulo 7 en la secci´n 7.3.0.2 se muestra la implementaci´n final de estos dos o o m´todos. e Una vez visto el funcionamiento de todas las clases de este sistema de soporte por separado, se muestra c´mo se relacionan entre s´ todas ellas de forma compleja, de forma o ı que si el d´ de ma˜ana hubiese que cambiar alg´n componente, el proceso fuese pr´ctiıa n u a camente de “Enchufar y Listo”. Se muestra a continuaci´n un diagrama de clases de esta o organizaci´n en la figura 6.49 donde se puede observar de forma simplificada la relaci´n o o entre las clases. Del mismo modo, tambi´n se puede observar como unas clases delegan parte de su e funcionamiento en otras, a trav´s del diagrama de secuencia de alto nivel que se muestra e en la figura 6.50. En ella se ve claramente el proceso de delegaci´n, gracias al cual, una de o las clases no se tiene que preocupar de realizar toda la operaci´n, sino que se realiza una o
    • 6.4. Arquitectura del Modelo 180 parte y deja que otra clase se encargue de uno de los trozos. Se podr´ tambi´n considerar ıa e esto como una aplicaci´n de “Divide y Vencer´s”, done en cada m´todo s´lo se trata una o a e o parte de la funci´nalidad a implementar, simplificando en gran medida la codificaci´n de o o los m´todos de las diferentes clases debido a que las operaciones que se realizan en cada e uno de ellos son mucho m´s sencillas que si se realizara todo junto. a
    • GeneralCalculadorDeOferta -split(colOfertable : Collection) : void +setCalculador(c : Calculador) : void -canBeApplied(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +CalcularMejorPara(c : Connection,colOfertable : Collection,dniPasPersona : String) : Collection +getAppliedOffers() : Collection +newOperation() +CalcularMejorPara(c : Connection,colOfertable : Collection,dniPasPersona : String) : Collection +setCalculador(c : Calculador) : void +getAppliedOffers() : Collection Rule <<create>> <<create>> +Rule(s : String) -getKey(s : String) : String -getArgs(s : String) : String[] +isOfferApplicable(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isRuleCorrectlyFormed(s : String) : boolean 1 <<call>> 1 6.4. Arquitectura del Modelo <<interface>> CalculadorDeOferta <<call>> <<interface>> Calculador 0..* +calculaMejorOferta(colProductos : Collection,colOfertasPosibles : Collection) : Collection +getAppliedOffers() : Collection <<call>> RulePartFactory CalculadorImpl +getValidRuleParts() : Collection +getRulePart(key : String,args : String[]) : RulePart +getRulePart(key : String) : RulePart +existsRulePart(key : String) : boolean <<instantiate>> +calculaMejorOferta(colProductos : Collection,colOfertasPosibles : Collection) : Collection -getBestOffer(colOf : Collection) : OfertaVO -getAmountDiscounted(colProductos : Collection,offer : OfertaVO) : Double -acumularOfertaEnOfertableCollection(colProductos : Collection,offer : OfertaVO) : void -calcAmount(col : Collection,discountTemp : Double) : Double +getAppliedOffers() : Collection 1 <<interface>> RulePart <<call>> +setArgs(args : String[]) : void +isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean +isCorrect(args : String[]) : boolean BestSetOfOffers <<create>> +BestSetOfOffers(nodes : Map) +getBestSetOfOffersIds() : ArrayList +getBestDiscount() : Double -getAllIncompatibleWith() : void Figura 6.49: Diagrama Simple del Sistema de Ofertas 181
    • 182 6.4. Arquitectura del Modelo Figura 6.50: Diagrama Secuencia de la Acci´n de Calcular o
    • Cap´ ıtulo 7 Implementaci´n o 7.1. Detalles Espec´ ıficos de la Implementaci´n o A continuaci´n ser´n especificados ciertos problemas que surgieron y detalles que se o a tuvieron en cuenta a la hora de implementar el sistema. El primer y principal problema surgido en la implementaci´n fue utilizando el manejao dor JDBC para MySQL en su versi´n m´s reciente, debido a que a la hora de conectarse o a con la base de datos lanzaba excepciones el driver diciendo que era imposible realizar la conexi´n, despu´s de contactar con comunidades de usuarios de MySQL y no encontrar o e soluci´n, habiendo tambi´n otros desarrolladores con el mismo problema, se decide inteno e tar solventar el problema analizando en profundidad la traza de la exepci´n. Esta idea fue o la acertada, ya que a trav´s de este an´lisis se concluye que el error era provocado por la e a codificaci´n de caracteres utilizada por defecto por la conexi´n. A partir de esta informao o ci´n y document´ndose sobre las opciones que se pueden pasar al driver de MySQL en el o a momento del establecimiento de conexi´n se consigui´ resolver el problema, public´ndolo o o a en las comunidades de MySQL1 y recibiendo agradecimientos de los usuarios que ten´ ıan ese mismo problemas. 1 La comunidad en la que se public´ la soluci´n de este problema fue en: http://forums.mysql.com/ o o exactamente en el siguiente hilo: http://forums.mysql.com/read.php?39,259743,259939#msg-259939 183
    • 7.1. Detalles Espec´ ıficos de la Implementaci´n o 184 Para la escritura del c´digo fuente de la aplicaci´n se siguieron las normas que se eso o tablecen en las Convenciones de C´digo Java (Java Code Conventions). De este modo o ser´ mucho m´s f´cil de entender el c´digo fuente de la aplicaci´n para futuros desarrollaa a a o o dores que realicen el mantenimiento de esta. Lo primero que se hizo fue decidir qu´ objetos se utilizar´ para manejar las fechas e ıan y los conjuntos de objetos del mismo tipo. Para el manejo de fechas se emple´ la clase o Calendar, ya que ofrece grandes ventajas a la hora de consultar una fecha y porque ya est´ pr´cticamente integrada en las tecnolog´ utilizadas. Por otro lado para gestionar a a ıas conjuntos de elementos se utiliz´ el objeto Collection, ya que este permite realizar bucles o utilizando un objeto Iterator, lo que hace algo m´s c´modo el trabajo del programador. a o Adem´s de la elecci´n de los objetos pertinentes para realizar la implementaci´n, tama o o bi´n se introdujeron unas clases xxxManager en la capa controlador de la aplicaci´n, estas e o clases tienen dos funciones fundamentales, la primera, realizar de cach´, para evitar reae lizar m´ltiples veces la misma consulta al modelo, y la segunda, sirve para amortiguar el u acceso al modelo en cuanto al n´mero de operaciones invocadas se refiere. Un ejemplo de u esto es la clase ReservationsManager que permite a˜adir nuevas l´ n ıneas de reserva a una reserva o incluso modificarla eliminando l´ ıneas, sin realizar esta operaci´n directamente o contra el modelo, sino que realiza los cambios internamente en su cach´ y luego en el moe mento de guardar hace los cambios todos juntos. Esto tambi´n posibilita que si el usuario e desea cancelar un proceso de modificaci´n, por ejemplo, los cambios que haya realizado o no haya que deshacerlos invocando a operaciones del modelo. Para la implementaci´n del cambio de idioma de la interfaz web se consideraron dos o opciones, la opci´n l´gica, ser´ que en cualquier momento el usuario pudiese cambiar el o o ıa idioma de la aplicaci´n y que inmediatamente le cambiase el idioma de donde est´ actualo a mente este usuario, pero esta no se pudo adoptar. Esta opci´n no se pudo implementar, o debido a que la unica forma de que se cargara el nuevo idioma ser´ cargar de nuevo la ´ ıa p´gina y si el usuario se encuentra en alg´n paso de un formulario se le enviar´ autom´tia u ıa a camente una petici´n id´ntica a la ultima operaci´n que realiz´. A ra´ de este comporo e ´ o o ız
    • 7.2. Implementaci´n de las Base de Datos o 185 tamiento no desado se decidi´ que, siempre que el usuario decidiese cambiar de idioma la o aplicaci´n, fuese redireccionado a la p´gina principal. De esta forma se consiguen evitar o a comportamientos err´neos o inconsistentes o 7.2. Implementaci´n de la Base de Datos o Aunque realmente las dos bases de datos que se utilizar´n se podr´ separar en dos bases a ıa de datos distintas, por motivos de simplicidad se consider´ que las tablas se creasen en o la misma base de datos. La base de datos se cre´ en localhost con el nombre bd hotel. A o continuaci´n se mostrar´n el proceso de creaci´n de las diferentes tablas y la inserci´n de o a o o los dos usuarios por defecto del sistema ’admin’ y ’receptionist’, a trav´s de unas consultas e SQL. 7.2.1. Implementaci´n de la Base de Datos General o A partir del dise˜o explicado en la secci´n 6.4.1.1 se puede sacar de forma sencilla la n o implementaci´n. o Con las consultas SQL que se muestran a continuaci´n se crean las tablas de la base o de datos General, y para cada tabla tambi´n se crean los ´ e ındices necesarios. Estos ´ ındices valdr´n para realizar consultas m´s r´pidas en esas tablas, por lo que se centrar´n en a a a a aquellos atributos por los que luego se har´n b´squedas m´s a menudo. a u a -- - - - - - - - - - - - - - - - - - - - -- C R E A T I N G TABLES -- - - - - - - - - - - - - - - - - - - - - CREATE TABLE P e r s o n a ( D n i _ P a s V a r c h a r (50) NOT NULL , E_mail V a r c h a r (255) NOT NULL , U s u a r i o _ C o n f Bit NOT NULL ,
    • 7.2. Implementaci´n de las Base de Datos o 186 N o m _ U s u a r i o V a r c h a r (255) NOT NULL , P a s s w o r d V a r c h a r (255) NOT NULL , Nombre V a r c h a r (255) NOT NULL , A p e l l i d o s V a r c h a r (255) NOT NULL , D i r _ C a l l e V a r c h a r (255) , Pais V a r c h a r (255) , C l i e n t e Bit NOT NULL , T e l e f o n o 1 V a r c h a r (100) , T e l e f o n o 2 V a r c h a r (100) , F e c h a _ N a c T i m e S t a m p NOT NULL D E F A U L T C U R R E N T _ T I M EST AM P , C O N S T R A I N T p k _ P e r s o n a P R I M A R Y KEY ( D n i _ P a s) ) Type = INNODB ; CREATE UNIQUE INDEX i n d i c e _ N o m _ U s u a r i o ON P e r s o n a( N o m _ U s u a r i o) ; CREATE INDEX i n d i c e _ N o m b r e ON P e r s o n a( Nombre ) ; CREATE INDEX i n d i c e _ A p e l l i d o s ON P e r s o n a( A p e l l i d o s) ; CREATE INDEX i n d i c e _ F e c h a _ N a c ON P e r s o n a( F e c h a _ N a c) ; CREATE TABLE F a c t u r a ( D n i _ P a s V a r c h a r (50) NOT NULL , N u m e r o _ F a c t u r a BigInt NOT NULL A U T O _ I N C RE MENT , Fecha T i m e S t a m p NOT NULL D E F A U L T C U R R E N T _ T I M EST AMP , T o t a l _ D e s c o n t a d o Double NOT NULL , Total Double NOT NULL , Pagada Bit NOT NULL , B o r r a d o r Bit NOT NULL ,
    • 7.2. Implementaci´n de las Base de Datos o O f e r t a s _ A p l i c a d a s V a r c h a r (255) NOT NULL , C O N S T R A I N T p k _ F a c t u r a P R I M A R Y KEY ( N u m e r o _ F a c t u r a ) , C O N S T R A I N T f k _ D n i _ P a s _ F a c t u r a F O R E I G N KEY ( D n i _ P a s) R E F E R E N C E S P e r s o n a( D n i _ P a s) ) Type = INNODB ; CREATE INDEX I n d i c e _ D n i _ P a s _ F a c t u r a ON F a c t u r a( D n i _ P a s) ; CREATE INDEX I n d i c e _ F e c h a _ F a c t u r a ON F a c t u r a( Fecha ) ; CREATE TABLE R e s e r v a ( D n i _ P a s V a r c h a r (50) NOT NULL , Codigo BigInt NOT NULL A U T O _ I N C REM ENT , F e c h a _ R e a l i z a c i o n T i m e S t a m p NOT NULL D E F A U L T C U R R E N T _ T I M ES TAM P , T e m p o r a l Bit NOT NULL , C O N S T R A I N T p k _ R e s e r v a P R I M A R Y KEY ( Codigo ) , C O N S T R A I N T f k _ D n i _ P a s _ R e s e r v a F O R E I G N KEY ( D n i _ P a s) R E F E R E N C E S P e r s o n a( D n i _ P a s) ) Type = INNODB ; CREATE INDEX I n d i c e _ D n i _ P a s _ R e s e r v a ON R e s e r v a( D n i _ P a s) ; CREATE INDEX I n d i c e _ F e c h a _ R e s e r v a ON R e s e r v a( F e c h a _ R e a l i z a c i o n ) ; CREATE TABLE H a b i t a c i o n ( Numero M e d i u m I n t NOT NULL , Piso S m a l l I n t NOT NULL , P r e c i o _ E x t r a Double NOT NULL D E F A U L T 0 , 187
    • 7.2. Implementaci´n de las Base de Datos o 188 C O N S T R A I N T p k _ H a b i t a c i o n P R I M A R Y KEY ( Numero ) ) Type = INNODB ; CREATE TABLE L i n e a s _ d e _ R e s e r v a ( C o d i g o _ R e s e r v a BigInt NOT NULL , Numero M e d i u m I n t NOT NULL , F e c h a _ I n i c i o T i m e S t a m p NOT NULL D E F A U L T C U R R E N T _ T I M EST AM P , F e c h a _ F i n T i m e S t a m p NOT NULL , D e s c u e n t o Double NOT NULL , T o t a l _ P a r c i a l Double NOT NULL , N u m e r o _ F a c t u r a BigInt NOT NULL , C a n c e l a d a Bit NOT NULL , C O N S T R A I N T p k _ L i n e a s _ d e _ R e s e r v a P R I M A R Y KEY ( C o d i g o _ Re serv a , Numero , F e c h a _ I n i c i o ) , C O N S T R A I N T f k _ N u m e r o _ L i n e a s _ d e _ R e s e r v a F O R E I G N KEY ( Numero ) R E F E R E N C E S H a b i t a c i o n ( Numero ) , C O N S T R A I N T f k _ C o d i g o _ R e s e r v a _ L i n e a s _ d e _ R e s e r v a F O R E I G N KEY ( C o d i g o _ R e s e r v a ) R E F E R E N C E S R e s e r v a( Codigo ) , C O N S T R A I N T f k _ N u m e r o _ F a c t u r a _ L i n e a s _ d e _ R e s e r v a F O R E I G N KEY ( N u m e r o _ F a c t u r a ) R E F E R E N C E S F a c t u r a( N u m e r o _ F a c t u r a ) ) Type = INNODB ; CREATE INDEX I n d i c e _ C o d i g o _ R e s e r v a _ L i n e a s _ d e _ R e s e r v a ON L i n e a s _ d e _ R e s e r v a ( C o d i g o _ R e s e r v a ) ; CREATE INDEX I n d i c e _ N u m e r o _ F a c t u r a _ L i n e a s _ d e _ R e s e r v a ON L i n e a s _ d e _ R e s e r v a ( N u m e r o _ F a c t u r a ) ; CREATE TABLE T i p o _ H a b i t a c i o n ( I d _ T i p o M e d i u m I n t NOT NULL A U T O _ I N C REM ENT , D e s c r i p c i o n Text , N u m _ P e r s o n a s SmallInt ,
    • 7.2. Implementaci´n de las Base de Datos o 189 P r e c i o _ B a s e Double NOT NULL , C O N S T R A I N T p k _ T i p o _ H a b i t a c i o n P R I M A R Y KEY ( I d _ T i p o) ) Type = INNODB ; CREATE TABLE E s _ d e _ t i p o ( Numero M e d i u m I n t NOT NULL , I d _ T i p o M e d i u m I n t NOT NULL , C O N S T R A I N T p k _ E s _ d e _ t i p o P R I M A R Y KEY ( Numero , I d _ T i p o) , C O N S T R A I N T f k _ N u m e r o _ H a b i t a c i o n F O R E I G N KEY ( Numero ) R E F E R E N C E S H a b i t a c i o n( Numero ) , C O N S T R A I N T f k _ I d _ T i p o _ T i p o _ H a b i t a c i o n F O R E I G N KEY ( I d _ T i p o) R E F E R E N C E S T i p o _ H a b i t a c i o n ( I d _ T i p o) ) Type = INNODB ; CREATE INDEX I n d i c e _ I d _ T i p o _ E s _ d e _ t i p o ON E s _ d e _ t i p o ( I d _ T i p o) ; CREATE INDEX I n d i c e _ N u m e r o _ E s _ d e _ t i p o ON E s _ d e _ t i p o ( Numero ) ; CREATE TABLE I n c i d e n c i a ( Numero M e d i u m I n t NOT NULL , I d _ S e c u n d a r i o M e d i u m I n t NOT NULL , Tipo V a r c h a r (255) , D e s c r i p c i o n Text , F e c h a _ R e g i s t r o T i m e S t a m p NOT NULL D E F A U L T C U R R E N T _ T I ME ST AMP , C O N S T R A I N T p k _ I n c i d e n c i a P R I M A R Y KEY ( Numero , I d _ S e c u n d a r i o ), C O N S T R A I N T f k _ N u m e r o _ H a b i t a c i o n _ I n c i d e n c i a F O R E I G N KEY ( Numero ) R E F E R E N C E S H a b i t a c i o n ( Numero ) ) Type = INNODB ; CREATE INDEX I n d i c e _ N u m e r o _ I n c i d e n c i a
    • 7.2. Implementaci´n de las Base de Datos o 190 ON I n c i d e n c i a ( Numero ) ; -- - - - - - - - - - - - - - - - - - - - -- Insert Admin -- - - - - - - - - - - - - - - - - - - - - INSERT INTO P e r s o n a ( Dni_Pas , E_mail , Usuario_Conf , Nom_Usuario , Password , Nombre , Apellidos , Dir_Calle , Pais , Cliente , Telefono1 , Telefono2) VALUES ( ’0 ’ , ’ ’ , 1 , ’ admin ’ , ’ admin ’ , ’ ’ , ’ ’ , ’ ’ , ’ ’ , 0 , ’ ’ , ’ ’) ; -- - - - - - - - - - - - - - - - - - - - -- Insert R e c e p t i o n i s t -- - - - - - - - - - - - - - - - - - - - - INSERT INTO P e r s o n a ( Dni_Pas , E_mail , Usuario_Conf , Nom_Usuario , Password , Nombre , Apellidos , Dir_Calle , Pais , Cliente , Telefono1 , Telefono2) VALUES ( ’1 ’ , ’ ’ , 1 , ’ r e c e p t i o n i s t ’ , ’ r e c e p t i o n i s t ’ , ’ ’ , ’ ’ , ’ ’ , ’ ’ , 0 , ’ ’ , ’ ’) ; 7.2.2. Implementaci´n de la Base de Datos de Ofertas o Despu´s de realizar el dise˜o que se ha detallado en la secci´n 6.4.1.2 ya se pueden crear e n o directamente las consultas SQL para construir esta base de datos, y adem´s, como en el a caso de la base de datos General, crear los ´ ındices necesarios para optimizar las futuras b´squedas. Las consultas que finalmente hay que ejecutar para tales objetivos son las u siguientes: -- - - - - - - - - - - - - - - - - - - - -
    • 7.2. Implementaci´n de las Base de Datos o 191 -- Base de datos Oferta : -- - - - - - - - - - - - - - - - - - - - CREATE TABLE T i p o _ O f e r t a ( I d _ T i p o M e d i u m I n t NOT NULL A U T O _ I N C RE MENT , Nombre V a r c h a r (255) , D e s c r i p c i o n Text , C O N S T R A I N T p k _ T i p o _ O f e r t a P R I M A R Y KEY ( I d _ T i p o) ) Type = INNODB ; CREATE INDEX I n d i c e _ N o m b r e _ T i p o _ O f e r t a ON T i p o _ O f e r t a( Nombre ) ; CREATE TABLE Oferta ( I d _ O f e r t a M e d i u m I n t NOT NULL A U T O _ I N C REME NT , D e s c u e n t o Double NOT NULL , D e s c r i p c i o n Text , F e c h a _ I n i c i o T i m e S t a m p NOT NULL D E F A U L T C U R R E N T _ T IM ES TAM P , F e c h a _ F i n T i m e S t a m p NOT NULL , R e g l a _ a _ c u m p l i r Text , I d _ T i p o M e d i u m I n t NOT NULL , B o r r a d o r Bit NOT NULL , D e s a c t i v a d a Bit NOT NULL , C O N S T R A I N T p k _ O f e r t a P R I M A R Y KEY ( I d _ O f e r t a) , C O N S T R A I N T f k _ I d _ T i p o _ T i p o _ O f e r t a F O R E I G N KEY ( I d _ T i p o) R E F E R E N C E S T i p o _ O f e r t a ( I d _ T i p o) ) Type = INNODB ; CREATE INDEX I n d i c e _ I d _ T i p o _ O f e r t a ON Oferta ( I d _ T i p o) ; CREATE TABLE A p l i c a b l e _ A ( I d _ T i p o M e d i u m I n t NOT NULL , Nombre V a r c h a r (255) NOT NULL ,
    • 7.3. Implementaciones del Sistema de Ofertas 192 C a n t i d a d _ M i n M e d i u m I n t NOT NULL D E F A U L T 1 , C O N S T R A I N T p k _ A p l i c a b l e _ A P R I M A R Y KEY ( Id_Tipo , Nombre ) ) Type = INNODB ; CREATE INDEX I n d i c e _ I d _ T i p o _ A p l i c a b l e _ A ON A p l i c a b l e _ A ( I d _ T i p o) ; CREATE TABLE I n c o m p a t i b l e _ C o n ( I d _ T i p o M e d i u m I n t NOT NULL , I d _ T i p o _ I n c o m p M e d i u m I n t NOT NULL , C O N S T R A I N T p k _ I n c o m p a t i b l e _ C o n P R I M A R Y KEY ( Id_Tipo , Id_Tipo_Incomp), C O N S T R A I N T f k _ I d _ T i p o _ I n c o m p a t i b l e _ C o n F O R E I G N KEY ( I d _ T i p o ) R E F E R E N C E S T i p o _ O f e r t a ( I d _ T i p o) , C O N S T R A I N T f k _ I d _ T i p o _ I n c o m p _ I n c o m p a t i b l e _ C o n F O R E I G N KEY ( I d _ T i p o _ I n c o m p ) R E F E R E N C E S T i p o _ O f e r t a( I d _ T i p o) ) Type = INNODB ; CREATE INDEX I n d i c e _ I d _ T i p o _ I n c o m p a t i b l e _ C o n ON I n c o m p a t i b l e _ C o n ( I d _ T i p o) ; CREATE INDEX I n d i c e _ I d _ T i p o _ I n c o m p _ I n c o m p a t i b l e _ C o n ON I n c o m p a t i b l e _ C o n ( I d _ T i p o _ I n c o m p ) ; 7.3. 7.3.0.1. Implementaci´nes del Sistema de Ofertas o Implementaci´n de Factor´ de Partes de Regla o ıa En esta secci´n se muestra como se realiz´ finalmente la implementaci´n de la clase o o o RulePartFactory, que se encarga de crear las partes de regla despu´s de que la clase Regla e la haya parseado.
    • 7.3. Implementaciones del Sistema de Ofertas 1 p a c k a g e hotel . modelo . m o d e l o o f e r t a . c a l c u l a d o r d e o f e r t a . regla ; 2 3 import java . io . B u f f e r e d R e a d e r ; 4 import java . io . F i l e N o t F o u n d E x c e p t i o n ; 5 import java . io . I O E x c e p t i o n; 6 import java . io . I n p u t S t r e a m; 7 import java . io . I n p u t S t r e a m R e a d e r ; 8 import java . util . A r r a y L i s t; 9 import java . util . C o l l e c t i o n ; 10 import java . util . I t e r a t o r; 11 12 import hotel . util . c o n f i g u r a t i o n . C o n f i g u r a t i o n P a r a m e t e r s M a n a g e r ; 13 import hotel . util . e x c e p t i o n s. model . MissingConfigurationParameterException ; 14 15 @ S u p p r e s s W a r n i n g s ( " u n c h e c k e d" ) 16 public class R u l e P a r t F a c t o r y { 17 18 19 p r i v a t e static Collection < String > a v a i l a b l e R u l e P a r t s = null ; 20 p r i v a t e final static String a v a i l a b l e R u l e P a r t s F i l e = " R u l e P a r t F a c t o r y / file " ; 21 22 static { 23 24 a v a i l a b l e R u l e P a r t s = new ArrayList < String >() ; 25 String temp = null ; 26 try { 27 Class m y C l a s s = R u l e P a r t F a c t o r y . class ; 28 ClassLoader classLoader = 29 m y C l a s s. g e t C l a s s L o a d e r () ; 193
    • 7.3. Implementaciones del Sistema de Ofertas 194 I n p u t S t r e a m i n p u t S t r e a m = c l a s s L o a d e r. 30 getResourceAsStream( C o n f i g u r a t i o n P a r a m e t e r s M a n a g e r . g e t P a r a m e t e r( 31 availableRulePartsFile )); I n p u t S t r e a m R e a d e r in = new I n p u t S t r e a m R e a d e r ( 32 i n p u t S t r e a m) ; B u f f e r e d R e a d e r f i l e B u f f e r = new B u f f e r e d R e a d e r ( in ) ; 33 34 while (( temp = f i l e B u f f e r . r e a d L i n e () ) != null ) { 35 if (! temp . equals ( " " ) ) { 36 a v a i l a b l e R u l e P a r t s . add ( temp ) ; 37 } 38 } 39 } catch ( F i l e N o t F o u n d E x c e p t i o n e ) { 40 System . out . p r i n t l n( " V a l i d V a l u e s F i l e Not Found " ) ; 41 } catch ( I O E x c e p t i o n e ) { 42 System . out . p r i n t l n( " U n a b l e d to read V a l i d V a l u e s F i l e " ) ; 43 } catch ( M i s s i n g C o n f i g u r a t i o n P a r a m e t e r E x c e p t i o n e ) { 44 System . out . p r i n t l n( " C o n f i g u r a t i o n p a r a m e t e r Not Found " ) 45 ; } 46 47 } 48 49 public Collection < String > g e t V a l i d R u l e P a r t s () { 50 return a v a i l a b l e R u l e P a r t s ; 51 52 } 53 54 public static R u l e P a r t g e t R u l e P a r t ( String key , String [] args ) { 55 56 57 if ( e x i s t s R u l e P a r t ( key ) ) { try {
    • 7.3. Implementaciones del Sistema de Ofertas 58 Class c o n c r e t e C l a s s = null ; 59 195 String c l a s s N a m e = ConfigurationParametersManager . getParameter( " R u l e P a r t F a c t o r y / " + key ) ; 60 61 c o n c r e t e C l a s s = Class . f o r N a m e( c l a s s N a m e ) ; 62 R u l e P a r t r = ( R u l e P a r t) c o n c r e t e C l a s s . n e w I n s t a n c e () ; 63 r . s e t A r g s( args ) ; 64 return r ; } catch ( M i s s i n g C o n f i g u r a t i o n P a r a m e t e r E x c e p t i o n e ) 65 { return null ; 66 } catch ( C l a s s N o t F o u n d E x c e p t i o n e ) { 67 return null ; 68 } catch ( I l l e g a l A r g u m e n t E x c e p t i o n e ) { 69 return null ; 70 } catch ( S e c u r i t y E x c e p t i o n e ) { 71 return null ; 72 } catch ( I n s t a n t i a t i o n E x c e p t i o n e ) { 73 return null ; 74 } catch ( I l l e g a l A c c e s s E x c e p t i o n e ) { 75 return null ; 76 } 77 78 } 79 else return null ; 80 } 81 82 83 public static R u l e P a r t g e t R u l e P a r t ( String key ) { /* 84 * Igual al m´ todo anterior , solo que este crear un e 85 * nuevo R u l e P a r t sin a r g u m e n t o s
    • 7.3. Implementaciones del Sistema de Ofertas 196 */ 86 } 87 88 public static b o o l e a n e x i s t s R u l e P a r t ( String key ) { 89 90 Iterator < String > iter = a v a i l a b l e R u l e P a r t s . i t e r a t o r () ; 91 String aux = " " ; 92 b o o l e a n cent = false ; 93 while ( iter . h a s N e x t () ) { 94 aux = iter . next () ; 95 if ( aux . c o m p a r e T o( key ) ==0) { cent = true ; 96 } 97 98 } 99 return cent ; } 100 101 } 7.3.0.2. Implementaci´n de Calculador o Los pasos que realiza el m´todo ’calcularMejorPara’ del objeto Calculador, se pueden e observar claramente con el trozo de c´digo fuente que los realiza: o 1 2 public Collection < Ofertable > C a l c u l a r M e j o r P a r a ( C o n n e c t i o n c , Collection < Ofertable > colOfertable , String dniPasPersona) 3 throws I n t e r n a l E r r o r E x c e p t i o n { 4 5 // Aqui d i v i d i m o s la c o l e c c i o n de O f e r t a b l e s i n i c i a l en O f e r t a b l e C o l l e c t i o n s segun su tipo 6 7 8 split ( c o l O f e r t a b l e ) ;
    • 7.3. Implementaciones del Sistema de Ofertas 9 197 S Q L O f e r t a D A O OF = S Q L O f e r t a D A O F a c t o r y . getDAO () ; 10 11 // R e c u p e r a m o s TODA la lista de o f e r t a s p o s i b l e s 12 13 Collection < OfertaVO > c o l O f e r t a = new ArrayList < OfertaVO >() ; 14 Collection < OfertaVO > temp ; 15 int i = 1; 16 while (( temp = OF . g e t B y D e s a c t i v a d a (c , false , i , 21) ) . size () ==21) { 17 temp . remove (20) ; 18 c o l O f e r t a. addAll ( temp ) ; 19 i = i +20; 20 } 21 if ( temp . size () <21) { c o l O f e r t a. addAll ( temp ) ; 22 23 24 } // Fin r e c u p e r a c i o n lista 25 26 // Ahora nos q u e d a m o s solo con las que son a p l i c a b l e s segun n u e s t r a regla 27 28 ArrayList < OfertaVO > o f A p l i c a b l e s = new ArrayList < OfertaVO >() ; 29 ArrayList < OfertaVO > a l O f e r t a = new ArrayList < OfertaVO >() ; 30 a l O f e r t a. addAll ( c o l O f e r t a ) ; 31 Iterator < OfertaVO > iterOf = a l O f e r t a. i t e r a t o r () ; 32 O f e r t a V O m y O f A u x = null ; 33 while ( iterOf . h a s N e x t () ) { 34 m y O f A u x = iterOf . next () ; 35 if ( c a n B e A p p l i e d ( myOfAux , colDeCol , d n i P a s P e r s o n a ) ) { o f A p l i c a b l e s . add ( m y O f A u x) ; 36 37 }
    • 7.3. Implementaciones del Sistema de Ofertas 38 } 39 198 // Ya solo nos quedan las que p o d e m o s a p l i c a r segun nuetra regla 40 // Y ahora l l a m a m o s a n u e s t r o c a l c u l a d o r p r e f e r i d o para que 41 nos c a l c u l e 42 Collection < Ofertable > col = 43 this . c a l c u l a d o r . c a l c u l a M e j o r O f e r t a ( colDeCol , 44 ofAplicables); 45 this . c o l O f A p p l i e d = this . c a l c u l a d o r. g e t A p p l i e d O f f e r s () ; 46 return col ; 47 } En el siguiente trozo de c´digo se puede ver como es el funcionamiento b´sico del m´todo o a e ’calculaMejorOferta’ de la clase CalculadorImpl, ya que para realizar ciertas operaciones delega su funcionamiento en otro m´todo auxiliar: e 1 public Collection < Ofertable > c a l c u l a M e j o r O f e r t a ( 2 Collection < O f e r t a b l e C o l l e c t i o n C hu n kV O > colProductos , 3 Collection < OfertaVO > c o l O f e r t a s P o s i b l e s ) 4 throws I n t e r n a l E r r o r E x c e p t i o n { 5 6 // P r i m e r o hay que d i v i d i r las o f e r t a s por tipos , ya que de cada tipo solo se va a poder a p l i c a r una y solo una oferta . 7 8 9 Map < Long , ArrayList < OfertaVO > > byTipo = new HashMap < Long , ArrayList < OfertaVO > >() ; 10 Iterator < OfertaVO > iter = c o l O f e r t a s P o s i b l e s . i t e r a t o r () ; 11 O f e r t a V O ofAux = null ; 12 while ( iter . h a s N e x t () ) {
    • 7.3. Implementaciones del Sistema de Ofertas 13 ofAux = iter . next () ; 14 199 if ( byTipo . c o n t a i n s K e y ( ofAux . g e t I d T i p o () ) ) { byTipo . get ( ofAux . g e t I d T i p o () ) . add ( ofAux ) ; 15 16 } 17 else { 18 ArrayList < OfertaVO > a = new ArrayList < OfertaVO >() ; 19 a . add ( ofAux ) ; 20 byTipo . put ( ofAux . g e t I d T i p o () , a ) ; } 21 22 } 23 24 Map < Long , Double > o f f e r T y p e V s D i s c o u n t = new HashMap < Long , Double >() ; 25 26 // R e c o r r o todos los tipos de ofertas , c a l c u l o el maximo d e s c u e n t o que se puede hacer sobre los o f e r t a b l e s que me pasan y anhado estos v a l o r e s al mapa , para que luego mi o p t i m i z a d o r ( B e s t S e t O f O f f e r s ) me d e v u e l v a las que se pueden apicar para que p r o d u z c a n el mayor d e s c u e n t o. 27 28 Collection < Long > tipos = byTipo . keySet () ; 29 Iterator < Long > t i p o s I t e r = tipos . i t e r a t o r () ; 30 Long l o n g A u x = null ; 31 O f e r t a V O b e s t A u x = null ; 32 while ( t i p o s I t e r. h a s N e x t () ) { 33 l o n g A u x = t i p o s I t e r. next () ; 34 b e s t A u x = this . g e t B e s t O f f e r ( byTipo . get ( l o n g A u x) ) ; 35 this . m y P r o x y M a p . put ( longAux , b e s t A u x) ; 36 } 37 38 tipos = this . m y P r o x y M a p. keySet () ; 39 t i p o s I t e r = tipos . i t e r a t o r () ;
    • 7.3. Implementaciones del Sistema de Ofertas 40 200 while ( t i p o s I t e r . h a s N e x t () ) { 41 l o n g A u x = t i p o s I t e r. next () ; 42 o f f e r T y p e V s D i s c o u n t . put ( longAux , this . g e t A m o u n t D i s c o u n t e d ( colProductos , this . m y P r o x y M a p. get ( l o n g A u x) ) ) ; 43 44 45 } 46 47 48 49 try { B e s t S e t O f O f f e r s b e s t O f f e r s = new B e s t S e t O f O f f e r s ( offerTypeVsDiscount); 50 this . m y B e s t S e t O f O f f e r s T y p e s = b e s t O f f e r s. g e t B e s t S e t O f O f f e r s I d s () ; 51 Iterator < Long > i t e r B e s t = this . m y B e s t S e t O f O f f e r s T y p e s . i t e r a t o r () ; 52 53 while ( i t e r B e s t. h a s N e x t () ) { this . a c u m u l a r O f e r t a E n O f e r t a b l e C o l l e c t i o n ( 54 colProductos , this . m y P r o x y M a p. get ( i t e r B e s t. next () ) ) ; 55 56 } 57 58 // Ahora anhado todos los o f e r t a b l e s 59 60 Iterator < O f e r t a b l e C o l l e c t i o n C h un k VO > i t e r O f e r t a b l e C o l = c o l P r o d u c t o s . i t e r a t o r () ; 61 62 while ( i t e r O f e r t a b l e C o l . h a s N e x t () ) { 63 this . m y F i n a l O f e r t a b l e C o l . addAll ( 64 i t e r O f e r t a b l e C o l . next () . e x t r a c t O f e r t a b l e C o l l e c t i o n () ) ; 65 }
    • 7.3. Implementaciones del Sistema de Ofertas 201 66 } catch ( I n t e r n a l E r r o r E x c e p t i o n e ) { 67 throw e ; 68 } catch ( S Q L E x c e p t i o n e ) { 69 throw new I n t e r n a l E r r o r E x c e p t i o n ( " SQL E x c e p t i o n : in 70 SimpleCalculator"); } 71 72 return this . m y F i n a l O f e r t a b l e C o l ; 73 74 } 7.3.0.3. Implementaci´n de una Parte de Regla o No hay mejor forma de ver c´mo se implementar´ una nueva parte de regla es con o ıa un ejemplo, as´ que a continuaci´n se muestra la implementaci´n de la parte de regla ı o o PersonBornBefore, la forma de crear una nueva es an´loga a esta. a 1 p a c k a g e hotel . modelo . m o d e l o o f e r t a . c a l c u l a d o r d e o f e r t a . regla . partes ; 2 3 import java . util . C a l e n d a r; 4 import java . util . C o l l e c t i o n ; 5 import javax . sql . D a t a S o u r c e ; 6 import hotel . modelo . m o d e l o o f e r t a . c a l c u l a d o r d e o f e r t a . regla . R u l e P a r t; 7 import hotel . modelo . m o d e l o o f e r t a . oferta . vo . O f e r t a V O; 8 import hotel . modelo . m o d e l o o f e r t a . util . o f e r t a b l e c o l l e c t i o n . OfertableCollectionChunkVO ; 9 import hotel . modelo . p e r s o n a. dao . S Q L P e r s o n a D A O ; 10 import hotel . modelo . p e r s o n a. dao . S Q L P e r s o n a D A O F a c t o r y ; 11 import hotel . util . sql . G e n e r a l D a t a S o u r c e ; 12 13 public class P e r s o n B o r n B e f o r e i m p l e m e n t s R u l e P a r t {
    • 7.3. Implementaciones del Sistema de Ofertas 202 14 15 p r i v a t e I n t e g e r day ; 16 p r i v a t e I n t e g e r month ; 17 p r i v a t e I n t e g e r year ; 18 19 public P e r s o n B o r n B e f o r e () {} 20 21 public void s e t A r g s ( String [] args ) { 22 day = 23 month = new I n t e g e r( args [1]) ; 24 year = new I n t e g e r( args [2]) ; 25 new I n t e g e r( args [0]) ; } 26 27 28 public b o o l e a n i s R u l e P a r t A p p l i c a b l e T o ( O f e r t a V O of , Collection < O f e r t a b l e C o l l e c t i o n C hu n kV O > colDeCol , String dniPas ) { 29 try { 30 System . out . p r i n t l n( " entro " ) ; 31 S Q L P e r s o n a D A O p e r s D A O = S Q L P e r s o n a D A O F a c t o r y . getDAO () ; 32 D a t a S o u r c e ds = new G e n e r a l D a t a S o u r c e () ; 33 C a l e n d a r f e c h a N a c i m i e n t o = p e r s D A O. f i n d P e r s o n a ( ds . g e t C o n n e c t i o n () , 34 dniPas ) . g e t F e c h a N a c () ; 35 C a l e n d a r c = C a l e n d a r. g e t I n s t a n c e () ; 36 c . clear () ; 37 c . set ( year , month -1 , day ) ; 38 c . s e t L e n i e n t ( false ) ; 39 c . g e t T i m e () ; 40 System . out . p r i n t l n( c . t o S t r i n g () ) ; 41 System . out . p r i n t l n( f e c h a N a c i m i e n t o . t o S t r i n g () ) ; 42 return c . c o m p a r e T o( f e c h a N a c i m i e n t o ) >=0; 43 } catch ( E x c e p t i o n e ) {
    • 7.3. Implementaciones del Sistema de Ofertas return false ; 44 } 45 46 203 } 47 48 49 public b o o l e a n i s C o r r e c t( String [] args ) { if ( args . length ==3) { if ( args [0]!= null &&( args [0]. c o m p a r e T o( " " ) !=0) 50 51 && args [1]!= null &&( args [1]. c o m p a r e T o( " " ) !=0) 52 && args [2]!= null &&( args [2]. c o m p a r e T o( " " ) !=0) ) { try { 53 54 I n t e g e r day = new I n t e g e r( args [0]) ; 55 I n t e g e r month = new I n t e g e r( args [1]) ; 56 I n t e g e r year = new I n t e g e r( args [2]) ; 57 C a l e n d a r c = C a l e n d a r. g e t I n s t a n c e () ; 58 c . clear () ; 59 c . set ( year , month -1 , day ) ; 60 c . s e t L e n i e n t( false ) ; 61 c . g e t T i m e () ; 62 return true ; 63 } 64 catch ( E x c e p t i o n e ) { 65 return false ; } 66 67 } 68 else return false ; 69 } 70 else if ( args . length <3) { return false ; 71 72 } 73 else { 74 75 for ( int i =3; i < args . length ; i ++) { if (( args [ i ]!= null ) &&( args [ i ]. c o m p a r e T o( " " ) !=0) ) {
    • 7.4. Software Necesario para Desplegar la Aplicaci´n o 204 return false ; 76 } 77 } 78 79 } 80 return true ; } 81 82 } 7.4. Software Necesario para Desplegar la Aplicaci´n o Para que la aplicaci´n funcione correctamente se necesita tener instalado el siguiente o software. M´quina virtual Java SE 6.0 a Es necesario tener intalada la m´quina virtual de Java SE 6.0 o posterior ya que fue a esta la utilizada en la compilaci´n de la aplicaci´n. o o Servidor de Aplicaciones Web Apache Tomcat 6.0.20 Es necesario tener intalado un servidor de aplicaciones web, en este caso se utilizar´ el a servidor Apache Tomcat 6.0.20 o superior. Gestor de Bases de Datos MySQL 5.0 Se necesita tener instalado el gestor de base de datos MySQL en su versi´n 5.0 o o superior, para almacenar las bases de datos necesarias para el funcionamiento del sistema desarrollado. 7.4.1. Instalaci´n y Configuraci´n del Software Necesario o o Junto con la aplicaci´n se provee adem´s del sofware que esta necesita para funcionar, a o a continuaci´n se explica brevemente c´mo intalarlo y configurarlo. El desarrollo e instalao o
    • 7.4. Software Necesario para Desplegar la Aplicaci´n o 205 ci´n de esta aplicaci´n se realiz´ en un entorno Linux, concretamente en una distribuci´n o o o o ’Ubuntu 8.10’, por lo que se realizar´ la explicaci´n para este sistema operativo. a o Para instalar el software se crear´ un directorio llamado ’software’ dentro de la carpeta a personal del usuario. M´quina virtual Java SE 6.0 a 1. Desempaquetar el archivador ’jdk1.6.0 16.tar.gz’. 2. Copiar la carpeta ’jdk1.6.0 16’ resultante en el directorio /usr/lib/jvm/ 3. Exportar las variables de entorno JAVA HOME y JRE HOME, y las a˜adimos n al PATH, a˜adiendo las siguientes l´ n ıneas al final del fichero de configuraci´n del o int´rprete de comandos, en este caso ser´ en ’$HOME/.bashrc’: e a 1 JAVA_HOME =/ usr / lib / jvm / jdk1 .6.0 _16 / jre / 2 export JAVA_HOME 3 PATH = $JAVA_HOME / bin : $PATH 4 5 JRE_HOME =/ usr / lib / jvm / jdk1 .6.0 _16 / jre / 6 export JRE_HOME 7 PATH = $JRE_HOME / bin : $PATH Servidor de Aplicaciones Web Apache Tomcat 6.0.20 1. Desempaquetar el archivador ’apache-tomcat-6.0.20.tar.gz’. 2. Copiar la carpeta ’apache-tomcat-6.0.20’ resultante en el directorio $HOME/software/ n 3. Exportar la variable de entorno CATALINA HOME, y la a˜adimos al PATH, a˜adiendo la siguiente l´ n ınea al final del fichero de configuraci´n del int´rprete o e de comandos, en este caso ser´ en ’$HOME/.bashrc’: a 1 C A T A L I N A _ H O M E = $HOME / software / apache - tomcat -6.0.20/ 2 export C A T A L I N A _ H O M E 3 PATH = $ C A T A L I N A _ H O M E / bin : $PATH
    • 7.4. Software Necesario para Desplegar la Aplicaci´n o 206 4. Una vez instalado se procede a su configuraci´n a˜adiendo la siguiente l´ o n ınea en su fichero de configuraci´n ($HOME/software/apache-tomcat-6.0.20/conf/tomcato users.xml) 1 < user name =" tomcat " password =" tomcat " roles =" tomcat , manager "/ > 5. Para arrancar y apagar el servidor se utilizan los scripts ’startup.sh’ y ’shutdown.sh’ contenidos en el directorio $HOME/software/apache-tomcat-6.0.20/bin/ Gestor de Bases de Datos MySQL 5.0 1. Desempaquetar el archivador ’mysql-5.0.67-linux-i686-glibc23.tar.gz’. 2. Copiar la carpeta ’mysql-5.0.67-linux-i686-glibc23’ resultante en el directorio $HOME/software/ 3. Se crea el directorio donde MySQL deber´ almacenar las bases de datos, por a ejemplo, $HOME/.MyDATA . 4. Se crea un fichero de configuraci´n para MySQL en $HOME/.my.cnf con el o siguiente contenido (en este caso es mejor substituir $HOME por la ruta del directorio personal): 1 [ mysqld ] 2 datadir = $HOME /. MyDATA 5. Hay que colocarse dentro del directorio $HOME/software/mysql-5.0.67-linuxi686-glibc23/ y ejecutar el siguiente comando para crear las bases de datos ’mysql’ y ’test’: 1 scripts / m y s q l _ i n s t a l l _ d b 6. Exportar la variable de entorno MYSQL HOME, y la a˜adimos al PATH, n a˜adiendo la siguiente l´ n ınea al final del fichero de configuraci´n del int´rprete o e de comandos, en este caso ser´ en ’$HOME/.bashrc’: a
    • 7.4. Software Necesario para Desplegar la Aplicaci´n o 1 MYSQL_HO ME = $HOME / software / mysql -5.0.67 - linux - i686 - glibc23 2 export MYSQL_HOM E 3 207 PATH = $MYSQL_HOM E / bin : $PATH 7. Una vez exportadas las variables de entorno hay que proceder al arranque del gestor ejecutando el siguiente comando: 1 mysqld 8. Despu´s de arrancar el servidor de MySQL hay que crear la base de datos que e va a utilizar la aplicaci´n y darle permisos a esta, para crear la base de datos o se utilizar´ el comando: a 1 mysqladm in -u root create bd_hotel A continuaci´n se entra en la consola de MySQL para crear un nuevo y usuario o y darle permisos. Para entrar en la consola hay que ejecutar: 1 mysql -u root Y para crear el usuario y sus permisos, desde la consola de MySQL se teclea lo siguiente y se ejecuta (para salir se utiliza el comando ’quit’): 1 GRANT ALL PRIVILEGE S ON bd_hotel .* 2 TO h o t e l a p p @ l o c a l h o s t IDENTIFIE D BY ’ hotelapp ’ , 3 h o t e l a p p @ l o c a l h o s t . localdoma i n IDENTIFIED BY ’ hotelapp ’; 9. Para parar el servidor de MySQL se ejecuta lo siguiente: 1 mysqladm in -u root shutdown Herramienta Maven para Gesti´n de Proyectos o Esta herramienta no es necesario instalarla para que la aplicaci´n funcione, pero es o de gran utilidad para futuras modificaciones o desarrollos.
    • 7.5. Organizaci´n de los Directorios del Proyecto o 208 1. Desempaquetar el archivador ’apache-maven-2.2.1.tar.gz’. 2. Copiar la carpeta ’apache-maven-2.2.1’ resultante en el directorio $HOME/software/ 3. Exportar la variable de entorno MAVEN HOME, y la a˜adimos al PATH, n a˜adiendo la siguiente l´ n ınea al final del fichero de configuraci´n del int´rprete o e de comandos, en este caso ser´ en ’$HOME/.bashrc’: a 1 MAVEN_HOM E = $HOME / software / apache - maven -2.2.1 2 export MAVEN_HOME 3 PATH = $MAVEN_HO M E / bin : $PATH 4. Una vez exportado el PATH ya se puede utilizar el comando ’mvn’ para arrancarlo. 7.5. Organizaci´n de los Directorios del Proyecto o Para la realizaci´n de este proyecto se ha mantenido la estructura fundamental generada o por la herramienta Maven 2 para proyectos web. Dentro de esta estructura se organizan todos los elementos necesarios para el funcionamiento de la aplicacaci´n, de la siguiente o forma: En /j2ee-hotel-app/src/main/java/es/udc/j2eehotelapp/hotel se encuentran las clases del modelo de la aplicaci´n, los DAO, las fachadas, y el modelo del sistema de ofertas. o En /j2ee-hotel-app/src/main/java/es/udc/j2eehotelapp/http es donde se pueden en- contrar las clases que implementan las acciones del controlador de Struts, as´ como los ı ActionForms utilizados para manejar los formularios, las clases que forman el controlador y la cadena de filtros. En /j2ee-hotel-app/src/main/resources/es/udc/j2eehotelapp/http/view/messages se encuentran los ficheros de las traducciones utilizadas para la internacionalizaci´n. o
    • 7.6. Instrucciones de Compilaci´n y Despliegue o 209 En /j2ee-hotel-app/src/main/resources est´n los ficheros utilizados para la configuraa ci´n de la aplicaci´n y para configurar las reglas del sistema de ofertas. o o En /j2ee-hotel-app/src/main/webapp se encuentra, divididos en subdirectorios seg´n el u usuario que vaya a hacer uso de ellas, las p´ginas JSP utilizadas para mostrar la IU de la a aplicaci´n. o En /j2ee-hotel-app/src/main/webapp/WEB-INF es donde est´n los diferentes ficheros a de configuraci´n del servidor (web.xml), de Struts (plain-struts-config.xml) y de Tiles o (tiles-defs.xml). 7.6. Instrucciones de Compilaci´n y Despliegue o Estos pasos se explicar´n desde dos puntos de vista, tener instalado Maven 2 o no tenerlo a instalado. Este proyecto se ha desarrollado para que en caso de no tener intalado Maven, se pueda compilar y desplegar sin problemas, se asume que s´ se tiene instalado el IDE ı Eclipse. Para ambos casos, una de las primeras cosas que hay que realizar es ejecutar el gestor de bases de datos MySQL. Para ello se utilizar´ el comando ’mysqld’. a A continuaci´n, en caso de no tener instalado Maven se procede a crear las tablas o manualmente utilizando las consultas SQL definidas en el fichero ’CreacionTablas.sql’ o, utilizando Maven ejecuntando el siguiente comando: ’mvn sql:execute’ Una vez se tiene preparada la base de datos es procede a arrancar el servidor Apache Tomcat ejecutando el scrip contenido en la carpeta ’bin’ de su instalaci´n, ’startup.sh’ o En la distribuci´n de este proyecto se entregan dos versiones, una para el desarrollo o con Maven y otra para el desarrollo sin ´l. Si se est´ utilizando Maven, el proyecto se ene a cuentra en ’j2ee-hotel-app’, hay que entrar dentro de esta carpeta y ejecutar los siguientes comandos para compilar y generar el ’.war’ utilizado para desplegar la aplicaci´n: o
    • 7.6. Instrucciones de Compilaci´n y Despliegue o 210 ’mvn clean’ para eliminar cualquier compilaci´n anterior. o ’mvn package’ para compilar y generar el .war para desplegar. En caso de no utilizar Maven, se usar´n los proyectos contenidos en ’hotel’ y ’hotel-app’. a Ambos son dos proyectos de Eclipse, por lo que se pueden importar directamente en este entorno de desarrollo. En el proyecto hotel-app se encuentra el modelo y el controlador de la aplicaci´n y es compilado autom´ticamente por eclipse. Por otro lado se encuentra o a el proyecto ’hotel’ donde est´n las p´ginas JSP, la configuraci´n de struts, etc. Para que a a o este segundo proyecto funcione correctamente se debe crear una librer´ .jar del primer ıa proyecto y copiarla en la raiz de este. Una vez realizado esto hay que proceder a generar el fichero .war, para lo que se utilizar´ la herramienta ’jar’, se posiciona justo fuera de a ’hotel’ y se ejectuta ’jar cvfm hotel.war hotel’. Cuando se haya generado el paquete .war se copia en el directorio webapps de la instalaci´n de Apache Tomcat y para ejecutarlo simplemente se abre el navegador web y se o especifica la siguiente URL: http://localhost:8080/nombrePaquete.
    • Cap´ ıtulo 8 Pruebas Para probar que todo funciona correctamente se han ido realizando diversos tipos de pruebas a lo largo del desarrollo del proyecto. Entre estas pruebas destacan las de Unidad, para las cuales se utiliz´ el framework JUnit, estas pruebas se realizar para probar que o ante una entrada determinada en un m´todo, este siempre devuelve lo esperado. e Se realizaron pruebas de unidad de todos los objetos DAO de sus m´todos m´s ime a portantes para comprobar que todo el intercambio de informaci´n con la base de datos o se realizaba correctamente, posteriormente, a medida que se fueron desarrollando las distintas fachadas del modelo se realizaban pruebas de unidad de los m´todos que ser´ e ıan utilizados m´s frecuentemente y aquellos que realizasen operaciones m´s complejas y ver, a a de esta forma, que todo funcionase conforme a lo esperado. Una vez realizadas todas las pruebas de unidad del modelo y viendo que todas ten´ ıan un resultado positivo, se desarrolla el resto del proceso hasta la interfaz gr´fica, una vez a hecho esto se hacen diversas pruebas para comprobar que todo funciona conforme a las especificaciones establecidas por el usuario. Dos de los casos m´s complejos que hubo que probar fueron, la realizaci´n de reservas, a o y que el sistema de ofertas calculase correctamente el descuento para una factura. En el primer caso se cubrieron todos los pasos posibles de realizaci´n de reservas: en varios o 211
    • 212 pasos, de una sola l´ ınea de reserva, y se comprobaron los posibles casos de error como que no hubiese habitaciones suficientes. En el caso de las ofertas, la funcionalidad cr´ ıtica que hab´ que probar era que calculase ıa correctamente el conjunto de ofertas compatibles que ofreciera el mayor descuento. Para ello previamente se establecieron todas las posibles relaciones de incompatibilidad entre 5 ofertas, se realizaron los c´lculos pertinentes a mano, y se comprob´ que el resutado a o calculado por el sistema de ofertas era el esperado en todos los casos de prueba.
    • Cap´ ıtulo 9 Planificaci´n y Evaluaci´n de o o Costes En este cap´ ıtulo se muestra la planificaci´n del proyecto teniendo en cuenta las fases o de la metodolog´ descrita por el Proceso Unificado. Estas fases se han detallado en el ıa apartado 4.2. Y se puede observar de forma gr´fica como se preceden unas a otras en el a gr´fico de Gantt de la figura 9.1. Adem´s tambi´n se puede ver con claridad como hay a a e en ciertas ocasiones en las cuales se pueden estar realizando dos tareas simult´nemente, a estableci´ndose de esa forma una relaci´n comienzo-comienzo entre ellas. e o Adem´s de indicar la planificaci´n de las diferentes tareas que forma el desarrollo del a o proyecto, tambi´n se hace una evaluaci´n de los costes de realizaci´n de dichas tareas. e o o Para cada tarea se necesita uno o varios empleados, y para la realizaci´n de este proyecto o se cuenta con un analista y un progamador. El sueldo del analista se ha fijado en 20e/hora y el del programador en 30e/hora, en estos sueldos se incluye el coste de seguridad social, el uso de equipos e instalaciones, etc. Y se ha establecido que la jornada laboral sea de 8:00 a 13:00 cada d´ (5 horas/d´ 5 d´ a la semana. ıa ıa), ıas A continuaci´n, en la tabla 9.1 se muestra la planificaci´n de las diferentes tareas y el o o coste asociado a cada una de ellas. 213
    • 214 Id Tarea Nombre Inicio Fin Duraci´n o 1 1.1 1.1.1 1.1.2 1.1.3 1.1.4 2 2.1 2.1.1 2.1.2 2.1.3 3 3.1 3.1.1 3.1.2 3.1.3 3.2 3.2.1 3.2.2 3.2.3 3.2.4 3.3 3.3.1 3.3.2 3.3.3 3.3.4 4 4.1 4.1.1 4.1.2 Concepci´n o + Iteraci´n 1 (I) o ++ Modelado de Negicio (I1) ++ An´lisis de Requisitos (I1) a ++ Dise˜o (I1) n ++ Implementaci´n/Pruebas (I1) o Elaboraci´n o + Iteraci´n 1 (E) o ++ An´lisis de Requisitos (E1) a ++ Dise˜o (E1) n ++ Implementaci´n/Pruebas (E1) o Construcci´n o + Iteraci´n 1 (C) o ++ An´lisis de Requisitos (C1) a ++ Dise˜o (C1) n ++ Implementaci´n/Pruebas (C1) o + Iteraci´n 2 (C) o ++ An´lisis de Requisitos (Sistema Ofertas) (C2) a ++ Dise˜o (Sistema Ofertas) (C2) n ++ Dise˜o (C2) n ++ Implementaci´n/Pruebas (C2) o + Iteraci´n 3 (C) o ++ An´lisis de Requisitos (Sistema Reglas) (C3) a ++ Dise˜o (Sistema Reglas) (C3) n ++ Dise˜o (C3) n ++ Implementaci´n/Pruebas (C3) o Transici´n o + Iteraci´n 1 (T) o ++ Despliegue (T1) ++ Documentaci´n de Usuario (T1) o Abr 14 Abr 14 Abr 14 Abr 15 Abr 16 Abr 17 Abr 21 Abr 21 Abr 21 Abr 23 Abr 28 May 4 May 4 May 4 May 4 May 6 May 22 May 22 May 25 May 22 May 25 Jun 22 Jun 22 Jun 22 Jun 22 Jun 22 Jul 27 Jul 27 Jul 27 Jul 27 Abr 20 Abr 20 Abr 14 Abr 15 Abr 16 Abr 20 May 1 May 1 Abr 22 Abr 27 May 1 Jul 24 May 22 May 4 May 8 May 22 Jun 19 May 25 May 28 May 28 Jun 19 Jul 24 Jun 22 Jun 24 Jun 24 Jul 24 Jul 31 Jul 31 Jul 27 Jul 31 5d 5d 1d 1d 1d 2d 9d 9d 2d 3d 4d 60d 14d 4h 4h 4d 12d 20d 1h 1d 3d 4d 20d 25d 4h 2d 3d 25d 5d 5d 1d 5d 600 600 100 100 100 300 1100 1100 200 300 600 10410 2280 80 400 1800 3800 100 300 400 3000 4330 80 200 300 3750 725 725 150 575 e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e Programador Analista, Programador Total PROYECTO Abr 14 Jul 31 79d 12835 e Analista, Programador Cuadro 9.1: Planificaci´n - Tabla de Tareas o Coste (e) Asignada a Analista Analista Analista Programador Analista Analista Programador Analista Analista Programador Analista Analista Analista Programador Analista Analista Analista Programador
    • 215 Figura 9.1: Planificaci´n - Diagrama de Gantt o
    • Cap´ ıtulo 10 Conclusiones y Futuras L´ ıneas de Trabajo Al t´rmino del desarrollo de este proyecto se puede decir que se han cumplido todos los e objetivos que hab´ que alcanzar con su realizaci´n. ıa o Uno de los objetivos principales era el aprendizaje de la plataforma J2EE para el desarrollo de aplicaciones web, as´ como del resto de tecnolog´ especificadas en el cap´ ı ıas ıtulo 1, alcanzando as´ los conocimientos esperados. ı Adem´s del objetivo did´ctico, este proyecto cumple con las especificaciones y los rea a quisitos para los cuales estaba orientado. Aunque algunos de estos requisitos ten´ cierta ıan complejidad, se consigui´ de igual forma llevarlos a cabo. o Entre los requisitos que deber´ cumplir destacan los siguientes: ıa La gesti´n de usuarios de la aplicaci´n funciona correctamente y conforme a lo o o esperado, alta de nuevos usuarios, baja de usuario, modificaci´n de sus datos, etc. o Adem´s para el recepcionista del hotel se le proporcionan funcionalidades para dar a de alta a nuevos clientes, modificar sus datos, o realizar una b´squeda de un cliente u 217
    • 218 por varios campos a la vez, de esta forma el recepcionista podr´ seleccionar al cliente a que desee y trabajar con ´l. e La gesti´n de reservas, que era una de las partes algo complejas de la aplicaci´n, se o o consigui´ realizar con ´xito, en esta parte destaca que la selecci´n de ofertas la hace o e o la aplicaci´n autom´ticamente despues de haber realizado la reserva, mientras que o a en otros productos del mercado esto debe realizarlo el cliente a la hora de reservar una estancia. Vease la figura 10.1. Figura 10.1: Gesti´n de Reservas de Otra Aplicaci´n o o A ra´ de estos funcionamientos poco correctos de las aplicaciones comerciales actuaız les, se decidi´ implementar un sistema de ofertas que se aplique autom´ticamente o a cuando se realiza la reserva. Este fue el sistema, con diferencia, m´s complejo de a toda la aplicaci´n, ya que hubo que definir un lenguaje de reglas para las ofertas y o un sistema de resoluci´n de incompatibilidades. o Adem´s de estos subsistemas, se desarrollaron con ´xito los de gesti´n de habitacioa e o nes, facturas y ofertas.
    • 219 En futuras ampliaciones de este proyecto, se podr´ implementar un sistema de pago que ıa soporte el pago de una reserva a trav´s de diferentes medios, PayPal, tarjeta de cr´dito, e e etc. Otra posible ampliaci´n ser´ la realizaci´n de un gestor de contenido para el portal o ıa o del Hotel. Este gestor de contenido deber´ posibilidar la publicaci´n de noticias y su ıa o internacionalizaci´n, y una gesti´n de las fotograf´ de la galer´ o o ıas ıa.
    • Ap´ndice A e Manuales para la Utilizaci´n de la o Aplicaci´n o Esta aplicaci´n es muy f´cil de utilizar e intuitiva, pero hay algunos aspectos, como las o a operaciones que debe realizar el usuario que no lo son tanto y deben ser explicadas. Por esta raz´n se crean estos manuales de usuario. o A.1. Manual Com´ n a Todos u Cuando se entra la aplicaci´n y a´n no se ha autenticado, simplemente se ve la p´gina o u a principal que contiene noticias y las ofertas disponibles actualmente, pero adem´s de eso a el usuario que no est´ autenticado s´lo podr´ acceder al contenido est´tico del portal, a o ıa a como puede ser la galer´ de im´genes. ıa a La p´gina principal, como se puede ver en la figura A.1 ofrece diversas operaciones, a aparte de navegar por el contenido est´tico permite registrarse como nuevo usuario y a autentificarse si ya se est´ registrado. a 221
    • A.1. Manual Com´n a Todos u 222 Figura A.1: P´gina Principal del Portal a Si el usuario decide darse de alta debe hacer clic en donde pone ’Registrarse’ y esto lo llevar´ al formulario de registro que se muestra en la figura A.2 que debe cubrir con sus a datos personales. Figura A.2: P´gina Registro de Nuevo Usuario a
    • A.1. Manual Com´n a Todos u 223 Si por otro lado el usuario ya est´ registrado y desea entrar en la aplicaci´n, deber´ pina o a char sobre ’Autentificaci´n’ y esto lo llevar´ a la p´gina de autentificaci´n que se muestra o a a o en la figura A.3 donde ingresar´ su nombre de usuario en la aplicaci´n y su contrase˜a. a o n Figura A.3: P´gina Autentificaci´n a o Una vez introducidos los datos, se le da a entrar y esto lleva al usuario a su p´gina a principal, que variar´ dependiendo de su rol dentro del sistema, en este caso habr´ tres a a tipos de usuarios distintos: Usuario/Cliente, Recepcionista y Administrador. Se mostrar´n a sus p´ginas principales en sus respectivos manuales de usuario. a
    • A.2. Manual Espec´ ıfico para el Usuario A.2. 225 Manual Espec´ ıfico para el Usuario Una vez autentificado en el sistema, se le presenta al usuario su p´gina principal, como a se muestra en la figura A.4, donde podr´ elegir diversas acciones como: cambiar sus datos, a hacer nuevas reservas, consultar reservas, etc. Figura A.4: P´gina Principal del Usuario a Aqu´ en la p´gina principal se le muestran al usuario las distintas operaciones que puede ı a realizar en un panel lateral izquierdo, ordenadas por categor´ ıas. Estas categor´ son: ıas ’Personal’ y ’Reservas’. ’Personal’ contiene las siguientes operaciones: ’Actualizar info. registro’, ’Salir’ y ’Darse de baja’. Y la categor´ de ’Reservas’ tiene: ’Nueva Reserva’ y ’Ver Reservas’. ıa A continuaci´n se explican cada una de las operaciones por separado: o Actualizar info. registro Esta operaci´n presenta un formulario como el de la figura A.2 en el cual el usuario o podr´ cambiar la informaci´n de su perfil cuando desee. Adem´s si quiere tambi´n a o a e
    • A.2. Manual Espec´ ıfico para el Usuario 226 podr´ cambiar su contrase˜a escribiendo simplemente una nueva, dejando ese campo a n en blanco si no lo quiere hacer. Salir Esta operaci´n realiza la simple acci´n de salir de la cuenta, por lo que el usuario o o deja de estar autentificado, si desea volver a entrar deber´ autentificarse de nuevo. a Darse de Baja Esta operaci´n permite al usuario darse de baja en el sistema, pero antes de hacerlo o se le muestra una p´gina de aviso como la de la figura A.5 en la que se le pregunta a si desea de verdad darse de baja, si responde afirmativamente, deja de estar dado de alta en el sistema. Figura A.5: P´gina de Aviso al Darse de Baja a Nueva Reserva Esta operaci´n permite al usuario crear una nueva reserva para los d´ que desee. o ıas El usuario podr´ a˜adir en una misma reserva, estancias para diferentes d´ y tipos a n ıas de habitaci´n, para realizar dicha operaci´n se le muestra un formulario como el de o o la figura A.6.
    • A.2. Manual Espec´ ıfico para el Usuario 227 Figura A.6: P´gina para Realizar una Nueva Reserva a El usuario debe cumplimentar todos los campos, en primer lugar tiene que elegir el tipo de habitaci´n que desea reservar, luego debe especificar la fecha de entrada y o de salida y por ultimo tiene que indicar el n´mero de habitaciones de ese tipo que ´ u desea. Para a˜adir a la reserva la nueva estancia deber´ darle a ’A˜adir’ o ’A˜adir n a n n y Finalizar’ si le da al boton de A˜adir luego podr´ seguir creando nuevas estancias n a para la reserva actual, y cuando lo desee le dar´ a ’Finalizar’ esto crear´ una nueva a a reserva y comunicar´ al usuario el n´mero de esta para que la pueda consultar en a u sus reservas mediante la operaci´n de ’Ver Reservas’. o Si en alg´n momento el usuario cumplimenta de forma err´nea alg´n campo o no u o u hay habitaciones disponibles para cubrir su solicitud se le comunicar´ para que, si a lo desea pueda cambiar las preferencias de su estancia. Ver Reservas Esta operaci´n permite al usuario todas las reservas que haya realizado hasta el o momento, ya est´n pagadas, canceladas o que ya se hayan disfrutado. Se mostrar´n e a en forma de lista como se puede observar en la figura A.7 y si tuviese m´s de diez a reservas se paginar´ el resultado. Adem´s en cada una de las reservas se permite al ıa a
    • A.2. Manual Espec´ ıfico para el Usuario 228 usuario realizar una serie de operaciones: ’Ver Factura’, ’Cancelar’ o consultar los datos de la reserva y, si a´n no se ha pagado ni disfrutado, modificarla. u Figura A.7: P´gina para Listar las Reservas a Si se desean consultar las estancias reservadas y/o modificarlas si es posible, basta con hacer clic en ’Cod. Reserva n’ y entrar as´ en un formulario a trav´s del cual ı e consultar y modificar su reserva. El formulario para modificar una reserva se muestra en la figura A.8 y permite ir eliminando y creando nuevas reservas de estancias y guardar los cambios realizados o cancelar el proceso cuando se estime oportuno. El formulario para a˜adir nuevas n estancias es el mismo que el que se utilizaba en crear nueva reserva, pero con menos botones ya que ahora solo ser´n necesarios ’A˜adir’ y ’Cancelar’. a n Adem´s de modificar una reserva, en la lista tambi´n se ofrece la posibilidad de a e cancelarla si a´n no se ha disfrutado. Simplemente haciendo clic en ’Cancelar’ la u reserva queda cancelada y en la columna de total aparecer´ el recargo que se le a cobr´ al cliente por esta cancelaci´n si previamente la reserva hab´ sido pagada. o o ıa
    • A.2. Manual Espec´ ıfico para el Usuario 229 Figura A.8: P´gina para Modificar una Reserva a Por otro lado se puede observar la factura de una reserva haciendo clic en ’Factura’. Si la factura ya se hab´ pagado esta aparecer´ marcada como pagada, y si no lo ıa a hab´ sido se mostrar´ la opci´n de pagar. Esto se muestra en la figura A.9. ıa a o Figura A.9: P´gina para Mostrar el Borrador de una Factura a
    • A.2. Manual Espec´ ıfico para el Usuario 230 En el apartado de ’Descuento’ se muestra el descuento conjunto que proporcionan todas aquellas ofertas que sean compatibles y se puedan aplicar en cada una de las l´ ıneas de la factura. Este c´lculo lo hace autom´ticamente el sistema. Si el importe a a convence al cliente, este s´lo tendr´ que proceder al pago de la factura a trav´s del o a e bot´n ’Pagar’ y cuando el pago est´ realizado la factura se muestra como pagada o e como en la figura A.10. Figura A.10: P´gina para Mostrar una Factura Pagada a
    • A.3. Manual Espec´ ıfico para el Recepcionista A.3. 231 Manual Espec´ ıfico para el Recepcionista Una vez autentificado en el sistema, se le presenta al recepcionista su p´gina principal, a como se muestra en la figura A.11, donde podr´ elegir diversas acciones como: cambiar a sus datos, dar de alta un cliente, buscar un cliente, hacer nuevas reservas para un cliente, consultar reservas de un cliente, ver habitaciones, etc. Figura A.11: P´gina Principal del Recepcionista a Aqu´ en la p´gina principal se le muestran al recepcionista las distintas operaciones que ı a puede realizar en un panel lateral izquierdo, ordenadas por categor´ Estas categor´ ıas. ıas son: ’Clientes’, ’Habitaciones’ y ’Personal’. ’Personal’ contiene las siguientes operaciones: ’Actualizar info. registro’ y ’Salir’. Estas operaciones son las mismas que se le ofrecen a un usuario normal, consultar las operaciones ’Actualizar info. registro’ y ’Salir’ en las p´ginas 225 y 226. En la categor´ ’Habitaciones’ a ıa se muestra la operaci´n ’Ver habitaciones’ y en ’Clientes’ se muestran ’Nuevo Cliente’ y o ’Buscar Cliente’.
    • A.3. Manual Espec´ ıfico para el Recepcionista 232 A continuaci´n se explican cada una de las operaciones por separado: o Ver Habitaciones Esta operaci´n permite al recepcionista ver las habitaciones del hotel para luego o consultar los datos de cada una en particular. Para esto se le muestra al recepcionista una lista de habitaciones como la de la figura A.12 Figura A.12: P´gina para Listar las Habitaciones para el Recpecionista a Para consultar los datos espec´ ıficos de un tipo de habitaci´n simplemente basta o con presionar el enlace sobre el tipo de habitaci´n y se mostrar´n los datos en un o a formulario como el que se muestra en la figura A.13
    • A.3. Manual Espec´ ıfico para el Recepcionista 233 Figura A.13: P´gina para Mostrar los Datos de un Tipo de Habitaci´n a o Nuevo Cliente Esta operaci´n permite al recepcionista dar de alta a un nuevo cliente, para ello o se le muestra un formulario como el de la figura A.14 donde el recepcionista debe cumplimentar los datos personales del nuevo cliente. Una vez cumplimentados los datos ya puede trabajar con el cliente dado de alta de la misma forma que si lo buscase y le diese a seleccionar cliente como se explicar´ en a la siguiente operaci´n ’Buscar Cliente’ o
    • A.3. Manual Espec´ ıfico para el Recepcionista 234 Figura A.14: P´gina para Dar de Alta un Nuevo Cliente a Buscar Cliente Esta operaci´n permite al recepcionista buscar a un cliente especificando parte o la o totalidad de su nombre, apellidos y/o DNI. Para realizarlo se le presenta un formulario como el que se muestra en la figura A.15 en el cual introduce los par´metros por a los que se desea buscar y se presiona el bot´n de ’Buscar’. Luego se muestra una lista o de los clientes que concuerdan con los par´metros de b´squeda como la de la figura a u A.16 en donde proporciona la posibilidad de seleccionar el cliente que se desee para trabajar con ´l, es decir, para poder realizarle reservas, consultarlas, etc. Una vez e seleccionado el cliente deseado se vuelve a la p´gina principal del recepcionista, pero a en este caso se muestran opciones a mayores como se puede observar en la figura A.17.
    • A.3. Manual Espec´ ıfico para el Recepcionista Figura A.15: P´gina para Buscar Clientes a Figura A.16: P´gina para Listar los Clientes Buscados a 235
    • A.3. Manual Espec´ ıfico para el Recepcionista 236 Figura A.17: P´gina Principal del Recepcionista Despu´s de Seleccionar Cliente a e Como se puede observar ahora aumentan las categor´ y las operaciones que se ıas pueden realizar, puesto que ahora se pueden hacer cosas en nombre del cliente que se ha seleccionado. La nueva categor´ que aparece es ’Reservas’ en la cual aparecen las opciones de ıa ’Nueva Reserva’ y ’Ver Reservas’. Adem´s en la categor´ ’Clientes’ aparecen nuevas a ıa operaciones como son: ’Ver/Actualizar Perfil del Cliente’, ’Cerrar Cuenta del Cliente’ o ’Dar de Baja Cliente’. Nueva Reserva Esta operaci´n permite al recepcionista realizar una reserva a petici´n de un cliente, o o el proceso que se sigue es el mismo explicado en la p´gina 226 en la operaci´n ’Nueva a o Reserva’. Ver Reservas
    • A.3. Manual Espec´ ıfico para el Recepcionista 237 Esta operaci´n permite al recepcionista ver las reservas hechas por un cliente para, o en caso necesario, localizar y pagar o cancelar una reserva concreta a petici´n de o un cliente. Estos procesos son exactamente iguales a los explicados para un usuario normal en la operaci´n ’Ver Reservas’ en la p´gina 227. o a Ver/Actualizar Perfil del Cliente Esta operaci´n permite al recepcionista ver la informaci´n del perfil de un cliente o o y editarla si fuese necesario como si se tratase del propio cliente s´lo que no se o le permite, por ejemplo, cambiar la contrase˜a. Para ello se le presenta el mismo n formulario que el mostrado para realizar la operaci´n de ’Nuevo Cliente’ que se o puede ver en la p´gina 233 a Cerrar Cuenta del Cliente Esta operaci´n permite al recepcionista cerrar la cuenta del cliente con el que est´ trao a bajando, pasando a su p´gina principal como se mostraba en la figura A.11 de la a p´gina 231. Si desea volver a trabajar con ese u otro cliente deber´ volver a buscarlo a a y seleccionarlo. Dar de Baja Cliente Esta operaci´n permite al recepcionista dar de baja a un cliente del sistema a petici´n o o de este, tan pronto como lo haga se le mostrar´ un mensaje de aviso como el de la a figura A.5 de la p´gina 226, indicando al recepcionista que debe alertar al cliente y a persuadirlo para que no se de de baja. Si el recepcionista confirma de todas formas que desea realizar la operaci´n el cliente deja de estar dado de alta en el sistema y o por lo tanto se vuelve a la p´gina principal del recepcionista de la figura A.11 de la a p´gina 231. a
    • A.4. Manual Espec´ ıfico para el Administrador A.4. 239 Manual Espec´ ıfico para el Administrador Una vez autentificado en el sistema, se le presenta al administrdor su p´gina principal, a como se muestra en la figura A.18, donde podr´ elegir diversas acciones como: cambiar a sus datos, crear y administrar las ofertas, dar de alta habitaciones y modificar su precio. Figura A.18: P´gina Principal del Administrador a Aqu´ en la p´gina principal se le muestran al administrador las distintas operaciones que ı a puede realizar en un panel lateral izquierdo, ordenadas por categor´ Estas categor´ ıas. ıas son: ’Personal’, ’Ofertas’ y ’Habitaciones’. ’Personal’ contiene las siguientes operaciones: ’Actualizar info. registro’ y ’Salir’. Las operaciones de esta categor´ son las mismas que se le proporcionan a un usuario normal, ıa por lo que se pueden ver en la p´gina 225. En la categor´ de ’Ofertas’ se tienen operaciones a ıa que permiten ’Crear Ofertas’ y ’Ver Ofertas’. En la tercera categor´ ’Habitaciones’, se ıa, le proporcionan las siguientes opciones: ’Nueva Habitaci´n’, ’Ver Habitaciones’ y ’A˜adir o n Incidencia’.
    • A.4. Manual Espec´ ıfico para el Administrador 240 A continuaci´n se explican cada una de las operaciones por separado: o Crear Ofertas Esta operaci´n presenta un formulario como el de la figura A.19 en el cual el ado ministrador debe introducir los datos necesarios para dar de alta una nueva oferta, como se puede observar en la figura A.20. Figura A.19: P´gina para Crear una Nueva Oferta a
    • A.4. Manual Espec´ ıfico para el Administrador 241 Figura A.20: P´gina para Crear una Nueva Oferta (Rellenada) a En primer lugar se debe elegir el tipo de oferta al que se desea que pertenezca la oferta de entre los que se proporcionan. Si lo que se quiere es crear un nuevo tipo de oferta simplemente habr´ que a˜adirlo pinchando sobre el enlace ’Nuevo Tipo de a n Oferta’ como se explicar´ m´s adelante. a a Luego se cubrir´n las fechas de inicio de aplicaci´n y de fin, el descuento que se a o quiere que proporcione la oferta y la regla que tiene que definir cu´ndo se puea de aplicar la oferta. Para definir la regla se utiliza la nomenclatura ’NombreRegla1:Argumento1 &&NombreRegla2:Argumento1,[...],ArgumentoN &&[...] &&NombreReglaN:Argumento1,Argumento2’ pero sin ning´n tipo de espacios. A continuau ci´n se detallan los Nombre de Regla disponibles y sus argumentos necesarios: o • PersonBornBefore:(D´ ıa),(Mes),(A˜ o) Esta regla sirve para definir que se n le aplique la oferta a las personas que hayan nacido antes de la fecha indicada. ◦ (D´ N´mero entero especificando el d´ ıa): u ıa. ◦ (Mes): N´mero entero especificando el mes. u
    • A.4. Manual Espec´ ıfico para el Administrador 242 ◦ (A˜o): N´mero entero especificando el a˜o. n u n • PersonBornAfter:(D´ ıa),(Mes),(A˜ o) Esta regla sirve para definir que se n le aplique la oferta a las personas que hayan nacido despu´s de la fecha e indicada. ◦ (D´ N´mero entero especificando el d´ ıa): u ıa. ◦ (Mes): N´mero entero especificando el mes. u ◦ (A˜o): N´mero entero especificando el a˜o. n u n • PersonFrom:(Pa´ Esta regla sirve para definir que se le aplique la oferta a ıs) las personas de cierto Pa´ ıs ◦ (Pa´ Nombre del pa´ ıs): ıs. • ReservationDoneBefore:(D´ ıa),(Mes),(A˜ o) Esta regla sirve para definir n que se le aplique la oferta a los clientes que realicen la reserva (que la paguen) antes de la fecha indicada. ◦ (D´ N´mero entero especificando el d´ ıa): u ıa. ◦ (Mes): N´mero entero especificando el mes. u ◦ (A˜o): N´mero entero especificando el a˜o. n u n • true Esta regla sirve para definir que se le aplique la oferta a todas las personas. Como ya se ha mencionado, si el administrador lo desea puede dar de alta un nuevo tipo de oferta, teniendo en cuenta que debe definir diferentes aspectos, como por ejemplo las incompatibilidades, y aquellos conjuntos de productos a los que es aplicable el tipo de oferta creado. Para realizar esta operaci´n se le muestra al ado ministrador un formulario como el de la figura A.21 y al darle a ’Crear’ el nuevo tipo aparece disponible para ser seleccionado en el formulario que se acaba de ver para crear una oferta y ser´ creado de verdad cuando se cree la nueva oferta que lo a utilice. En este formulario se deben cumplimentar: el nombre del nuevo tipo de oferta y una descripci´n de este. Adem´s se mostrar´n una lista de posibles productos a los que o a a
    • A.4. Manual Espec´ ıfico para el Administrador 243 Figura A.21: P´gina para Crear un Nuevo Tipo de Oferta a podr´ ser aplicable la oferta de los cuales se eligir´n los que se deseen, indicando a a a su vez la cantidad m´ ınima que se debe ordenar para que se aplique la oferta. Por otro lado aparecer´n tambi´n todos los tipos de oferta que haya hasta el momento a e dados de alta en el sistema, y se deben marcar aquellos con los que se desea que el nuevo tipo sea incompatible, es decir, aquellos tipos de oferta con los cuales no se pueda aplicar conjuntamente una oferta del nuevo tipo que se est´ creando. a Ver Ofertas Esta operaci´n permite al administrador ver las ofertas que existen actualmente en el o sistema, la publicadas, las que no lo est´n y los borradores. Las ofertas se mostrar´n a a en una lista como la que se muestra en la figura A.22 y desde la cual se podr´ acceder a para ver los datos de una oferta en particular o un tipo de oferta. Si se desean realizar operaciones con una oferta en particular basta con hacer clic encima de su identificador y esto mostrar´ un formulario como el de la figura A.23 a indicando las operaciones que podemos realizar con ella. Si la reserva a´n est´ maru a cada como borrador se podr´n modificar sus datos, borrarla o publicarla, pero si ya a no es borrador s´lo se podr´ publicar en caso de que a´n no lo est´ y ’despublicar’ o a u e
    • A.4. Manual Espec´ ıfico para el Administrador 244 Figura A.22: P´gina para Listar las Ofertas a si ya hab´ sido publicada. Se le ofrece este mecanismo al administrador por si por ıa error publica una oferta que no deber´ ıa. Figura A.23: P´gina para Realizar Operaciones con las Ofertas a
    • A.4. Manual Espec´ ıfico para el Administrador 245 Adem´s de proporcionar la opci´n de consultar los datos de una oferta y modificarlos a o tambi´n se le permite al administrador consultar y modificar los datos de un tipo de e oferta a trav´s del formulario que se muestra en la figura A.24. Para ello simplemente e debe hacer clic en el nombre del tipo de oferta que aparece en la lista de ofertas en la columna correspondiente. Figura A.24: P´gina para Realizar Operaciones con los Tipos de Ofertas a Nueva Habitaci´n o Esta operaci´n permite al administrador dar de alta una nueva habitaci´n en el o o sistema. Esto lo debe hacer tan pronto como desee que el sistema se pueda utilizar, ya que si no hay habitaciones no se pueden hacer reservas. Para dar de alta una habitaci´n se muestra al administrador un formulario como el de la figura A.25 donde o deber´ especificar el n´mero que tendr´ la habitaci´n, el piso en el que estar´ la a u a o a habitaci´n y el precio extra que puede tener esta a mayores del precio que establezca o el tipo de habitaci´n. o
    • A.4. Manual Espec´ ıfico para el Administrador 246 Figura A.25: P´gina para Dar de Alta una Habitaci´n a o El tipo al que pertenecer´, lo puede elegir de la lista, pero si no est´ el deseado a a deber´ crear uno que se ajuste a lo que necesia haciendo clic en ’Nuevo Tipo de a Habitaci´n’. Esta operaci´n de nuevo tipo, le permite al administrador crear un o o nuevo tipo de habitaci´n a trav´s de un formulario como el que se muestra en la o e figura A.26 donde debe especificar una breve descripci´n, el n´mero de personas al o u que est´ destinado y el precio base que costar´. a a Figura A.26: P´gina para Crear un Nuevo Tipo de Habitaci´n a o
    • A.4. Manual Espec´ ıfico para el Administrador 247 Ver Habitaciones Esta operaci´n permite al administrador ver las habitaciones que est´n dadas de alta o a actualmente en el sistema. Las habitaciones se mostrar´n en una lista como la que a se muestra en la figura A.27 y desde la cual se podr´ acceder para ver los datos de a una oferta en particular o un tipo de oferta. Figura A.27: P´gina para Listar las Habitaciones para el Administrador a Para consultar los datos espec´ ıficos de una habitaci´n el administrador tiene que o hacer clic en ’Habitaci´n numero n’ y esto le mostrar´ un formulario como el de la o a figura A.28 mediante el cual podr´ consultar los datos de la habitaci´n deseada o a o modificarlos si lo desea.
    • A.4. Manual Espec´ ıfico para el Administrador 248 Figura A.28: P´gina para Consultar/Modificar los Datos de una Habitaci´n a o Adem´s se proporciona la opci´n de consultar yo modificar los datos de un tipo a o de habitac´n a trav´s del formulario que se muestra en la figura A.29. Para ello o e simplemente debe hacer clic en el nombre del tipo de habitaci´n que aparece en la o lista de habitaciones en la columna correspondiente. Figura A.29: P´gina para Consultar/Modificar los Datos de un Tipo de Habitaci´n a o
    • A.4. Manual Espec´ ıfico para el Administrador 249 Por otro lado en cada l´ ınea de la lista se proporciona un enlace para que el administrador pueda ver las incidencias de esa habitaci´n simplemente pinchando en o ´l. Al realizarlo se le muestra una lista con todas las incidencias registradas en esa e habitaci´n como se puede observar en la figura A.30. o Figura A.30: P´gina para Listar las Incidencias de una Habitaci´n a o A˜ adir Incidencia n Esta operaci´n permite al administrador registrar una incidencia ocurrida en una o habitaci´n. Para realizar este cometido se le presenta un formulario como el de la o figura A.31 donde el administrador debe cubrir lo siguiente: elegir la habitaci´n o a la que est´ relacionada la incidencia, definir el tipo de gravedad de la incidencia a (meramente informativo, a definir por el administrador), y una descripci´n completa o de lo ocurrido.
    • A.4. Manual Espec´ ıfico para el Administrador Figura A.31: P´gina para Registrar una Incidencia de una Habitaci´n a o 250
    • Ap´ndice B e Licencia del Proyecto - GPLv31 A continuaci´n se muestra el contenido de esta licencia, aunque por motivos de validez o legal se provee en ingl´s, se puede consultar una versi´n traducida en el siguiente enlace: e o http://www.viti.es/gnu/licenses/gpl.html B.1. General Public License (Version 3) Version 3, 29 June 2007 Copyright c 2007 Free Software Foundation, Inc. http://fsf.org/ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program–to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies 1 General Public License version 3 251
    • B.1. General Public License (Version 3) 252 of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers’ and authors’ protection, the GPL clearly explains that there is no warranty for this free software. For both users’ and authors’ sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users’ freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. Terms and Conditions 0. Definitions. “This License” refers to version 3 of the GNU General Public License.
    • B.1. General Public License (Version 3) 253 “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component,
    • B.1. General Public License (Version 3) 254 but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
    • B.1. General Public License (Version 3) 255 Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users’ Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work’s users, your or third parties’ legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its
    • B.1. General Public License (Version 3) 256 parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the
    • B.1. General Public License (Version 3) 257 same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any
    • B.1. General Public License (Version 3) 258 third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
    • B.1. General Public License (Version 3) 259 d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f ) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
    • B.1. General Public License (Version 3) 260 Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor’s “contributor version”.
    • B.1. General Public License (Version 3) 261 A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that
    • B.1. General Public License (Version 3) 262 is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others’ Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation.
    • B.1. General Public License (Version 3) 263 If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection
    • B.1. General Public License (Version 3) 264 with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. End of Terms and Conditions How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. <one line to give the program’s name and a brief idea of what it does.> Copyright (C) <textyear> <name of author> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: <program> Copyright (C) <year> <name of author> This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’. This is free software, and you are welcome to redistribute it under certain conditions; type ‘show c’ for details.
    • B.1. General Public License (Version 3) 265 The hypothetical commands show w and show c should show the appropriate parts of the General Public License. Of course, your program’s commands might be different; for a GUI interface, you would use an “about box”. You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see http://www.gnu.org/licenses/. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read http://www.gnu.org/philosophy/why-not-lgpl.html.
    • Bibliograf´ ıa [1] The Apache Software Foundation. Apache tomcat. Website, 1999. http://tomcat.apache.org/. [2] The Apache Software Foundation. Maven. Website, 2002. http://maven.apache.org/. [3] The Eclipse Foundation. Eclipse. Website, 2009. http://www.eclipse.org/. [4] Craig Larman. UML y Patrones. ISBN 84-205-3438-2. Prentice Hall. [5] Sun Microsystems. Java 2 platform, enterprise edition (j2ee). Website, 1994. http://java.sun.com/j2ee/overview.html. [6] Kenneth H. Rosen. Matem´tica discreta y sus aplicaciones. ISBN 84-481-4073-7. a McGraw Hill, 2005. [7] Deepak Alur; John Crupi y Dan Malks. Core J2EE Patterns. ISBN 0-13-064884-1. Prentice Hall. [8] Ted Husted; Cedric Dumoulin; George Franciscus y David Winterfeldt. Struts In Action. ISBN 1-930110-50-2. MANNING. [9] Ivar Jacobson; Grady Booch y James Rumbaugh. El Proceso Unificado De Desarrollo De Software. ISBN 84-7829-036-2. Addison Wesley, 1999. 267
    • Bibliograf´ ıa 268 [10] Bernardo Cascales Salinas; Pascual Lucas Saor´ Jos´ Manuel Mira Ros; Antonio ın; e A Jos´ Pallar´s Ruiz y Salvador S´nchez-Pedre˜o Gill´n. El libro de L TEX. ISBN e e a n e 84-205-3779-9. Prentice Hall. [11] MySQL y Sun Microsystems. Mysql. Website, 1995. http://www.mysql.com/. [12] Christopher Schmitt; Mark Trammel; Ethan Marcotte; Dunstan Orchard y Todd Dominey. CSS: Hojas de estilo en cascada para el dise˜o Web. ISBN 84-415-1954-4. n ANAYA, 2005.