xesthproyecto

300
Facultad de Inform´ atica de la Universidad de A Coru˜ na Departamento de Tecnolog´ ıas de la Informaci´ on y las Comunicaciones PROYECTO DE FIN DE CARRERA INGENIER ´ IA T ´ ECNICA INFORM ´ ATICA DE GESTI ´ ON Dise˜ no e Implementaci´on de una Aplicaci´on Web Java EE con Arquitectura MVC Destinada a Gestionar las Actividades de un Hotel Alumno: Sergio Pad´ ın Varela Director: Carlos Alberto Pan Berm´ udez Fecha: 29 de septiembre de 2009

Upload: wladimir-mendoza

Post on 05-Jul-2015

425 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Xesthproyecto

Facultad de Informatica de la Universidad de A CorunaDepartamento de Tecnologıas de la Informacion y las Comunicaciones

PROYECTO DE FIN DE CARRERA

INGENIERIA TECNICA INFORMATICA DE GESTION

Diseno e Implementacion de una Aplicacion Web Java EEcon Arquitectura MVC Destinada a Gestionar las

Actividades de un Hotel

Alumno: Sergio Padın Varela

Director: Carlos Alberto Pan Bermudez

Fecha: 29 de septiembre de 2009

Page 2: Xesthproyecto
Page 3: Xesthproyecto

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 carino, apoyo y animo que me ha dado en todo momento. A todos

ellos, muchısimas gracias.

Sergio Padın Varela

3

Page 4: Xesthproyecto
Page 5: Xesthproyecto

5

Dr. Carlos Alberto Pan Bermudez

Profesor de la Faculdad de Informatica de la Coruna

Departamento de Tecnologıas de la Informacion y las Comunicaciones

Universidad de A Coruna

CERTIFICA: Que la memoria titulada “Diseno e Implementacion de una Aplicacion

Web Java EE con Arquitectura MVC Destinada a Gestionar las Actividades de un Hotel”

ha sido realizada por Sergio Padın Varela bajo mi direccion y constituye su Proyecto

de Fin de Carrera de Ingenierıa Tecnica Informatica de Gestion.

En A Coruna, a 25 de septiembre de 2009

Dr. Carlos Alberto Pan Bermudez

Director del proyecto

Page 6: Xesthproyecto
Page 7: Xesthproyecto

7

Resumen:

El proyecto realizado consiste en desarrollar una Aplicacion Web para la gestion de

las reservas de un hotel o similar. Tambien hay que desarrollar todo lo necesario para la

realizacion de reservas, incluyendo entre otros la gestion de clientes y usuarios de la web,

las habitaciones, y los pagos de las mismas.

Ademas tambien se desarrolla un complejo sistema de ofertas, donde se permite crear

ofertas que puedan ser incompatibles unas con otras y basadas en reglas de aplicacion,

altamente configurables para especificar el contexto al cual se le puede aplicar dicha oferta.

Estas luego son utilizadas dinamicamente a la hora de realizar la factura que tiene que

abonar el cliente, en donde se calcula el conjunto de ofertas compatibles entre sı que mayor

descuento proporcionan sobre la factura.

La Aplicacion distingue tres roles principales: el usuario/cliente (de ahora en adelante el

cliente), el recepcionista y el administrador. Cada uno puede realizar una serie operaciones

sobre la aplicacion.

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, dandolos de alta, de baja,

actualizar sus perfiles o realizar reservas a su nombre. Para todo ello el recepcionista puede

buscar a los clientes por uno o mas parametros. Tambien tiene la posibilidad de cobrar

una reserva a un cliente o cancelarla, entre otras cosas.

El administrador es el usuario de la aplicacion que mas privilegios tiene. Este puede

anadir habitaciones, modificar precios y mantener todo el sistema de ofertas. Creando

nuevas ofertas, modificandolas, publicandolas o dandolas de baja. Este apartado es muy

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.

Page 8: Xesthproyecto
Page 9: Xesthproyecto

9

Lista de palabras clave:

Aplicacion Web, Java, J2EE, MVC, Struts, Apache Tomcat, MySQL, HTML, XML,

CSS, JSP, JSPX, JSTL, Tiles, JDBC, Data Access Object (DAO), Value Object (VO),

Hotel, Reserva, Facturacion, Ofertas, Reglas, Incompatibilidades.

Page 10: Xesthproyecto
Page 11: Xesthproyecto

Agradecimientos1

A D. Carlos Alberto Pan Bermudez (Profesor de la Facultad de Informatica, Universidad

de A Coruna), por la orientacion durante la realizacion del proyecto, ası como su ayuda a la

hora de resolver problemas puntuales durante el diseno e implementacion de la aplicacion.

A Dna. Marıa Luisa Carpente Rodrıguez (Profesor de la Facultad de Informatica, Uni-

versidad de A Coruna), por su ayuda a la hora de resolver de forma practica el grafo de

incompatibilidades entre las ofertas.

1En orden alfabetico

11

Page 12: Xesthproyecto
Page 13: Xesthproyecto

Indice general

Introduccion XIII

1. Herramientas y tecnologıas utilizadas 1

1.1. Herramientas y tecnologıas para el Diseno . . . . . . . . . . . . . . . . . . . 1

1.2. Herramientas y tecnologıas para la Implementacion . . . . . . . . . . . . . . 2

1.3. Herramientas y tecnologıas para la Documentacion . . . . . . . . . . . . . . 10

2. Estado actual de las tecnologıas utilizadas 13

3. Estudio de viabilidad 17

4. Introduccion al desarrollo realizado 21

4.1. El Proceso Unificado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.2. El Proceso Unificado en este Proyecto . . . . . . . . . . . . . . . . . . . . . 24

5. Requisitos del Sistema 29

5.1. Introduccion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

5.2. Actores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

5.3. Casos de Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

i

Page 14: Xesthproyecto

Indice general ii

5.3.1. Gestion de Usuarios Web . . . . . . . . . . . . . . . . . . . . . . . . 34

5.3.2. Gestion de Reservas Web . . . . . . . . . . . . . . . . . . . . . . . . 40

5.3.3. Gestion de Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

5.3.4. Gestion de Reservas . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

5.3.5. Gestion de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . . . 60

5.3.6. Gestion de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.4. Modelo de Casos de Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

5.4.1. Gestion de Usuarios Web . . . . . . . . . . . . . . . . . . . . . . . . 78

5.4.2. Gestion de Reservas Web . . . . . . . . . . . . . . . . . . . . . . . . 79

5.4.3. Gestion de Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

5.4.4. Gestion de Reservas . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

5.4.5. Gestion de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . . . 82

5.4.6. Gestion de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

6. Diseno de la aplicacion 85

6.1. Arquitectura General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

6.2. Capa de la Vista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

6.2.1. Hojas de Estilo - CSS . . . . . . . . . . . . . . . . . . . . . . . . . . 88

6.2.2. Paginas JSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

6.2.3. ActionForms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

6.2.4. Internacionalizacion . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

6.2.5. ApplicationObjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

6.3. Capa del Controlador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

Page 15: Xesthproyecto

Indice general iii

6.3.1. Patron Front Controller . . . . . . . . . . . . . . . . . . . . . . . . . 94

6.3.2. Patron Chain of Responsability . . . . . . . . . . . . . . . . . . . . . 96

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. Descripcion de los Subsistemas . . . . . . . . . . . . . . . . . . . . . 131

6.4.5. Sistema de Soporte - Modelo de Ofertas . . . . . . . . . . . . . . . . 166

7. Implementacion 183

7.1. Detalles Especıficos de la Implementacion . . . . . . . . . . . . . . . . . . . 183

7.2. Implementacion de las Base de Datos . . . . . . . . . . . . . . . . . . . . . . 185

7.2.1. Implementacion de la Base de Datos General . . . . . . . . . . . . . 185

7.2.2. Implementacion de la Base de Datos de Ofertas . . . . . . . . . . . . 190

7.3. Implementaciones del Sistema de Ofertas . . . . . . . . . . . . . . . . . . . 192

7.4. Software Necesario para Desplegar la Aplicacion . . . . . . . . . . . . . . . 204

7.4.1. Instalacion y Configuracion del Software Necesario . . . . . . . . . . 204

7.5. Organizacion de los Directorios del Proyecto . . . . . . . . . . . . . . . . . . 208

7.6. Instrucciones de Compilacion y Despliegue . . . . . . . . . . . . . . . . . . . 209

8. Pruebas 211

Page 16: Xesthproyecto

Indice general iv

9. Planificacion y Evaluacion de Costes 213

10.Conclusiones y Futuras Lıneas de Trabajo 217

A. Manuales para la Utilizacion de la Aplicacion 221

A.1. Manual Comun a Todos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

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 . . . . . . . . . . . . . . . . . . . 239

B. Licencia del Proyecto - GPLv3 251

B.1. General Public License (Version 3) . . . . . . . . . . . . . . . . . . . . . . . 251

Page 17: Xesthproyecto

Indice de figuras

4.1. Grafico del Proceso Unificado . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.1. CU: Gestion de Usuarios Web . . . . . . . . . . . . . . . . . . . . . . . . . . 78

5.2. CU: Gestion de Reservas Web . . . . . . . . . . . . . . . . . . . . . . . . . . 79

5.3. CU: Gestion de Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

5.4. CU: Gestion de Reservas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

5.5. CU: Gestion de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 82

5.6. CU: Gestion de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

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. Patron Front Controller General . . . . . . . . . . . . . . . . . . . . . . . . 95

6.6. Paquetes - Distribucion de Acciones . . . . . . . . . . . . . . . . . . . . . . 99

6.7. Diagrama Aplicacion de Front Controller . . . . . . . . . . . . . . . . . . . 100

6.8. Diagrama Entidad Relacion - General . . . . . . . . . . . . . . . . . . . . . 107

v

Page 18: Xesthproyecto

Indice de figuras vi

6.9. Modelo Relacional - General . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

6.10. Diagrama Entidad Relacion - Ofertas . . . . . . . . . . . . . . . . . . . . . . 110

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

Page 19: Xesthproyecto

Indice de figuras vii

6.31. Diagrama Simple de Gestion de Usuarios . . . . . . . . . . . . . . . . . . . 132

6.32. Actions y Exceptions de Gestion de Usuarios . . . . . . . . . . . . . . . . . 132

6.33. Diagrama Simple de Gestion de Clientes . . . . . . . . . . . . . . . . . . . . 135

6.34. Actions y Exceptions de Gestion de Clientes . . . . . . . . . . . . . . . . . . 136

6.35. Diagrama Simple de Gestion de Reservas . . . . . . . . . . . . . . . . . . . 139

6.36. Actions y Exceptions de Gestion de Reservas . . . . . . . . . . . . . . . . . 140

6.37. Diagrama Simple de Gestion de Habitaciones . . . . . . . . . . . . . . . . . 145

6.38. Actions de Gestion de Habitaciones . . . . . . . . . . . . . . . . . . . . . . . 146

6.39. Diagrama Simple de Gestion de Tipos de Ofertas . . . . . . . . . . . . . . . 151

6.40. Actions de Gestion de Tipos de Ofertas . . . . . . . . . . . . . . . . . . . . 152

6.41. Diagrama Simple de Gestion de Ofertas . . . . . . . . . . . . . . . . . . . . 156

6.42. Actions de Gestion de Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . 157

6.43. Diagrama de la Interfaz Ofertable . . . . . . . . . . . . . . . . . . . . . . . . 160

6.44. Diagrama Simple de Gestion de Facturas . . . . . . . . . . . . . . . . . . . . 162

6.45. Actions y Exceptions de Gestion de Facturas . . . . . . . . . . . . . . . . . 163

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 Accion de Calcular . . . . . . . . . . . . . . . . . 182

9.1. Planificacion - Diagrama de Gantt . . . . . . . . . . . . . . . . . . . . . . . 215

10.1. Gestion de Reservas de Otra Aplicacion . . . . . . . . . . . . . . . . . . . . 218

Page 20: Xesthproyecto

Indice de figuras viii

A.1. Pagina Principal del Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

A.2. Pagina Registro de Nuevo Usuario . . . . . . . . . . . . . . . . . . . . . . . 222

A.3. Pagina Autentificacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

A.4. Pagina Principal del Usuario . . . . . . . . . . . . . . . . . . . . . . . . . . 225

A.5. Pagina de Aviso al Darse de Baja . . . . . . . . . . . . . . . . . . . . . . . . 226

A.6. Pagina para Realizar una Nueva Reserva . . . . . . . . . . . . . . . . . . . . 227

A.7. Pagina para Listar las Reservas . . . . . . . . . . . . . . . . . . . . . . . . . 228

A.8. Pagina para Modificar una Reserva . . . . . . . . . . . . . . . . . . . . . . . 229

A.9. Pagina para Mostrar el Borrador de una Factura . . . . . . . . . . . . . . . 229

A.10.Pagina para Mostrar una Factura Pagada . . . . . . . . . . . . . . . . . . . 230

A.11.Pagina Principal del Recepcionista . . . . . . . . . . . . . . . . . . . . . . . 231

A.12.Pagina para Listar las Habitaciones para el Recpecionista . . . . . . . . . . 232

A.13.Pagina para Mostrar los Datos de un Tipo de Habitacion . . . . . . . . . . 233

A.14.Pagina para Dar de Alta un Nuevo Cliente . . . . . . . . . . . . . . . . . . 234

A.15.Pagina para Buscar Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . 235

A.16.Pagina para Listar los Clientes Buscados . . . . . . . . . . . . . . . . . . . . 235

A.17.Pagina Principal del Recepcionista Despues de Seleccionar Cliente . . . . . 236

A.18.Pagina Principal del Administrador . . . . . . . . . . . . . . . . . . . . . . . 239

A.19.Pagina para Crear una Nueva Oferta . . . . . . . . . . . . . . . . . . . . . . 240

A.20.Pagina para Crear una Nueva Oferta (Rellenada) . . . . . . . . . . . . . . . 241

A.21.Pagina para Crear un Nuevo Tipo de Oferta . . . . . . . . . . . . . . . . . . 243

A.22.Pagina para Listar las Ofertas . . . . . . . . . . . . . . . . . . . . . . . . . . 244

Page 21: Xesthproyecto

Indice de figuras ix

A.23.Pagina para Realizar Operaciones con las Ofertas . . . . . . . . . . . . . . . 244

A.24.Pagina para Realizar Operaciones con los Tipos de Ofertas . . . . . . . . . 245

A.25.Pagina para Dar de Alta una Habitacion . . . . . . . . . . . . . . . . . . . . 246

A.26.Pagina para Crear un Nuevo Tipo de Habitacion . . . . . . . . . . . . . . . 246

A.27.Pagina para Listar las Habitaciones para el Administrador . . . . . . . . . . 247

A.28.Pagina para Consultar/Modificar los Datos de una Habitacion . . . . . . . 248

A.29.Pagina para Consultar/Modificar los Datos de un Tipo de Habitacion . . . 248

A.30.Pagina para Listar las Incidencias de una Habitacion . . . . . . . . . . . . . 249

A.31.Pagina para Registrar una Incidencia de una Habitacion . . . . . . . . . . . 250

Page 22: Xesthproyecto
Page 23: Xesthproyecto

Indice de cuadros

3.1. Tabla de costes para estudio de viabilidad . . . . . . . . . . . . . . . . . . . 18

9.1. Planificacion - Tabla de Tareas . . . . . . . . . . . . . . . . . . . . . . . . . 214

xi

Page 24: Xesthproyecto
Page 25: Xesthproyecto

Introduccion

Determinacion de la situacion actual

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ıa mas personas planean sus vacaciones a traves de Internet, por lo que no solo

es bueno dar a conocer los servicios que se prestan, sino tambien dar la oportunidad de

poder contratar esos servicios este donde este el cliente.

Hoy en dıa muchas pequenas empresas hoteleras aun siguen registrando sus reservas

manualmente en un libro para tal efecto. Estas se producen normalmente por telefono,

no ofreciendo practicamente ninguna garantıa de que la reserva vaya a ser pagada, los

responsables del establecimiento dieron su palabra al cliente que llamo y esa estancia

puede que quede sin ocupar, con las posibles perdidas que ello pueda conllevar. Ademas

normalmente no tienen un sitio web que puedan usar para promocionarse, lo que implica

que solo se pueden dar a conocer a traves de anuncios o similares y esto supone un gasto

adicional para la empresa.

Las grandes firmas de hoteles y multinacionales no tienen todos esos problemas. La

mayorıa permite que se reserven habitaciones a traves de su sitio web y pide que se abone

el pago de dicha reserva, ası se aseguran que esta se va llevar a cabo. Las que no permiten

xiii

Page 26: Xesthproyecto

xiv

hacer el pago en el momento de la realizacion de la reserva tampoco pierden demasiado,

ya que la perdida de una estancia es compensada por la multitud que se hacen efectivas

debido a sus volumenes de negocio. Estas empresas tampoco se tienen que preocupar

demasiado por la publicidad, ya que pueden permitirse hacer campanas publicitarias por

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ıcil de llevar a

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 gestion

de un hotel, comenzando por desarrollar un sistema a traves del cual se puedan realizar

reservas y generar facturas, ası como gestionar las habitaciones, etc. Para esto se desarrolla

una Aplicacion Web, que permitira hacer reservas on-line del mismo modo que tambien

se podra gestionar el hotel en su totalidad, facil y comodamente.

Se pretende entre otras cosas que este proyecto sea facilmente ampliable, de forma que,

a medida que vayan surgiendo necesidades distintas dentro de la gestion de un hotel, se

pueda dar una solucion facil, rapida y lo mas elegante posible. Ademas se desarrolla de

forma que se pueda integrar de forma comoda la gestion del hotel y la gestion del sitio

web, ya que actualmente en el ambito de los hoteles hay la necesidad de darlos a conocer

a un mayor publico para ampliar el mercado.

Para comenzar se definen los usuarios que van a interactuar con la aplicacion. El Cliente,

el Recepcionista y el Administrador seran los usuarios principales, pero no los unicos, ya

que la aplicacion necesitara tambien tener como actor de soporte alguna entidad financiera

contra la cual se realizaran los pagos de las reservas.

Page 27: Xesthproyecto

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: ubicacion, fotografıas, etc.

El usuario tendra la posibilidad de crearse una cuenta en el portal web del hotel, con la

cual podra realizar distintas acciones. El usuario que este registrado podra modificar sus

datos personales en cualquier momento o darse de baja cuando lo desee. Tambien tendra la

posibilidad de realizar tantas reservas como quiera y luego podra pasar a administrarlas,

pudiendo ası cancelar o modificar las reservas efectuadas, o comprobar la factura para ver

cuanto tendrıa que pagar. Esta factura se calcula de forma dinamica aplicando el conjunto

de ofertas que descuenten la mayor cantidad de dinero a la factura. Una vez vista la fatura

podra pagarla en ese preciso momento, a partir del cual la reserva quedara hecha.

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 tambien reservas para un cliente.

En primer lugar se le da la opcion de actualizar sus datos personales. Tambien puede

buscar a un cliente en la base de datos por varios criterios, nombre, apellidos, etc. Si el

cliente no esta registrado, se le da la oportunidad de darlo de alta en el sistema, y si lo

esta se puede tambien modificar su perfil. A continuacion se le permite realizar la reserva

que el cliente le pueda pedir. Y cuando el cliente pague la reserva el empleado de recepcion

del hotel podra marcar la factura como pagada en la aplicacion.

Asimismo, puede consultar las reservas de un cliente, las habitaciones, precios y otras

consultas generales acerca del hotel.

El administrador de la aplicacion y del hotel tiene como actividades principales en

el sistema gestionar las distintas partes del mismo. Puede crear habitaciones, consultar

y modificar sus datos, tambien tiene la posibilidad de hacer lo mismo con los tipos de

habitaciones que son los que en realidad definen los precios y condiciones que tienen las

mismas.

Page 28: Xesthproyecto

xvi

Otra de las operaciones que puede realizar el administrador es la creacion y publicacion

de ofertas. Cuando el administrador crea una oferta, ademas de cubrir de que fecha a

que fecha la oferta sera aplicable, tambien debe especificar la regla que se debe cumplir

con respecto al contexto en el cual se hara efectiva la oferta, de esta forma se podra definir

mas concretamente los parametros que se deben de cumplir para que la oferta se pueda

aplicar. Mediante el uso de reglas se podra definir, por ejemplo, que una oferta solo se

pueda aplicar a los clientes de un determinado paıs que hayan nacido antes de una fecha

determinada y que paguen la reserva antes de un dıa fijado.

Estas reglas podran definirse a traves del lenguaje natural, siguiendo simplemente unas

condiciones en la escritura de las mismas, como que las diferentes partes en las que se divide

una regla esten separadas utilizando unos caracteres especiales. Por ejemplo, una posible

regla para decir que solo se puede aplicar a personas de Espana que nacieran antes del 20 de

Octubre de 1980 serıa la siguiente: “PersonFrom:Espana&&PersonBornBefore:20,10,1980”

El sistema de reglas desarrollado es altamente configurable de forma que se pueden

anadir nuevas reglas al sistema sin tener que alterar nada de lo que ya esta hecho. Ası de

este modo se podrıan definir en caso necesario, condiciones mas elaboradas, como por

ejemplo, que solo se pudiese aplicar a aquellas personas que desde la apertura del hotel

hayan gastado en el mas de una cantidad de dinero.

La internacionalizacion de la aplicacion es algo fundamental en este caso ya que al

tratarse de un hotel es imprescindible especificarlo todo en varios idiomas y ası llegar

mejor a clientes extranjeros. La aplicacion web tendra traducciones a Espanol, Gallego e

Ingles, y sera muy sencillo anadir nuevas traducciones en un futuro, de igual forma tambien

estaran internacionalizadas las fechas y los numeros, pero se dejan sin internacionalizar

los precios ya que todas las transacciones se haran y se calcularan en Euros.

Page 29: Xesthproyecto

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 realizacion de un proyecto software.

Capıtulo 1. En este capıtulo se detallan de forma breve todas las tecnologıas empleadas

en el desarrollo y documentacion del proyecto, desde las herramientas utilizadas para

realizar el codigo fuente de la aplicacion, hasta las tecnologıas empleadas para que esta

funcionase correctamente en el momento del despliege final de la misma.

Capıtulo 2. En este apartado se explica el estado de las tecnologıas utilizadas en la

actualidad, ası como la diferencia con otras tecnologıas disponibles en el mercado, y el

porque se utilizaron unas y no otras. Para esta elecion estuvo muy presente la idea de que

la aplicacion final deberıa poder licenciarse como software libre por lo que las licencias de

algunas tecnologıas impidieron su uso.

Capıtulo 3. Se estudia en este capıtulo la viabilidad del desarrollo de la aplicacion que

se realizara. En este estudio se tiene en cuenta desde el tiempo estimado que se empleara en

su desarrollo como el coste este conllevara, ademas de otras cuestiones como la posible

comercializacion del producto una vez terminado.

Capıtulo 4. En este capıtulo se indica la metodologıa que se sigue en el desarrollo del

proyecto. En este caso se detallan las caracterısticas del Proceso Unificado y sus diferentes

fases en el ciclo de desarrollo de la aplicacion.

Ademas se explica detalladamente lo que se hizo en cada una de estas fases en el proyecto,

indicando exactamente en que momento, iteracion, de la fase del Proceso Unificado se

realizo.

Page 30: Xesthproyecto

xviii

Capıtulo 5. Se detallan en este capıtulo todos los requisitos que regiran el desarrollo

del proyecto. En un primer lugar se analizaran textualmente y de forma general las fun-

cionalidades que debera contemplar la aplicacion, que luego seran detalladas exactamente

en un modelo de casos de uso.

Este modelo de casos de uso se explicara dividiendolo en subconjuntos de casos de uso

relacionados, y dentro de cada subconjunto se detallara cada uno de los casos de uso por

separado y se mostrara un diagrama de casos de uso para ver como se relacionan estos

con los actores que interactuaran con la aplicacion.

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 diseno del sistema final.

Se explican en este apartado las diferentes capas en las que se divide el sistema, basi-

camente se describe la arquitectura Modelo-Vista-Controlador utilizada. Despues de una

introduccion al diseno realizado se detalla el funcionamiento y el diseno de cada una de

las capas por separado.

En la capa modelo es donde se realiza especial incapie ya que es donde estara situa-

da toda la logica de negocio del sistema, donde realmente se implementaran los casos de

uso especificados en el modelo de casos de uso. Para desglosar esta capa, se realiza una

separacion en subsistemas, se puede identificar claramente cada uno de ellos con un sub-

conjunto de casos de uso y a continuacion se explica el diseno utilizado en estos subsistemas

acompanandolos en todo momento de los diagramas UML correspondientes.

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 explicacion textual de como deben operar e interacturar entre ellas y a

continuacion se hace un analisis mas formal apoyandose en un grafo de incompatibilidades

y su resolucion, realizado expresamente para solventar las cuestiones mas complejas del

Page 31: Xesthproyecto

xix

sistema. Por otro lado se explica tambien el funcionamiento del sistema de reglas y el

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 implementacion de

la aplicacion, ası como el software utilizado para su despliegue y configuracion. Ademas

tambien se expondran problemas surgidos durante la implementacion del proyecto y sus

soluciones.

Capıtulo 8. Este capıtulo de la memoria describe las diferentes pruebas realizadas para

probar el correcto funcionamiento de la aplicacion. Entre las pruebas hechas destacan las

pruebas de unidad, aunque no menos importantes son las pruebas de funcionalidad para

chequear que la aplicacion cumpliese con todos los requisitos de funcionalidad requeridos

al inicio del proyecto.

Capıtulo 9. En este capıtulo se establece la planificacion de tiempo y costes para la

realizacion del proyecto, ilustrado todo con un diagrama de Gantt.

Capıtulo 10. Este es el capıtulo donde se comentan las impresiones acerca del proyecto,

ası como las conclusiones sobre los conocimientos adquiridos y futuras posibles modifica-

ciones sobre este proyecto.

Page 32: Xesthproyecto
Page 33: Xesthproyecto

Capıtulo 1

Herramientas y tecnologıas

utilizadas

Para la realizacion de este proyecto se utilizaron distintas herramientas y tecnologıas,

desde el diseno y la implementacion, hasta la documentacion del sistema.

1.1. Herramientas y tecnologıas para el Diseno

ArgoUML Es una aplicacion para realizar diagramas UML escrita en Java y publicada

bajo la Licencia BSD open source. Dado que es una aplicacion Java, esta disponible en

cualquier plataforma soportada por Java. Aunque la interfaz grafica no es lo mejor del

mercado, la potencia para realizar diagramas y exportarlo a la mayorıa de los formatos

que se puedan querer, hace de esta aplicacion una herramienta de gran ayuda a la hora de

realizar los diagramas para desarrollar una aplicacion.

Ademas esta aplicacion permite realizar ingenierıa directa de diagramas UML a codigo,

pero no solo a codigo Java, sino tambien a otros lenguajes como C# o PHP. Tambien

permite la realizacion de ingenierıa inversa, generando un modelo a partir de codigo fuente.

Esto es muy util a la hora de documentar un proyecto, ya que de esta forma se asegura

1

Page 34: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 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 algun metodo, atributo, etc.

DIA Es una aplicacion grafica de proposito general para la creacion de diagramas, desa-

rrollada como parte del proyecto GNOME. Esta concebido de forma modular, con dife-

rentes paquetes de formas para diferentes necesidades.

Dia esta disenado como un sustituto de la aplicacion comercial Visio de Microsoft. Se

puede utilizar para dibujar diferentes tipos de diagramas. Actualmente se incluyen diagra-

mas entidad-relacion, diagramas UML, diagramas de flujo, diagramas de redes, diagramas

de circuitos electricos, etc. Nuevas formas pueden ser facilmente agregadas, dibujandolas

con un subconjunto de SVG e incluyendolas en un archivo XML.

El formato para leer y almacenar graficos es XML (comprimido con gzip, para ahorrar

espacio). Pero lo interesante, al igual que con ArgoUML es que puede producir salida en

multiples formatos como: EPS, SVG, PNG, etc. Y al igual que ArgoUML, Dia, gracias al

paquete ‘dia2code‘, puede generar el esqueleto del codigo a escribir a partir de un diagrama

UML.

1.2. Herramientas y tecnologıas para la Implementacion

Java EE Java Platform, Enterprise Edition, tambien conocida como J2EE es un con-

junto de especificaciones Java definidas para la construccion de aplicaciones empresariales.

Estas aplicaciones empresariales estan estructuradas en diferentes capas, donde cada una

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 mas

frecuentemente es la de modelo, vista y controlador.

El modelo es el que define la logica de negocio de la aplicacion, es totalmente indepen-

diente de la vista y del controlador. En el residen los objetos de la aplicacion incluyendo

sus datos y comportamiento.

Page 35: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 3

Por otro lado la vista es la encargada de la representacion de los datos en una interfaz

de usuario para interactuar con este. Esta capa tambien es independiente de las demas

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 ejecucion de operaciones

sobre bases de datos desde Java. Con este API se define una interfaz que permite interac-

tuar con gran variedad de bases de datos relacionales. Este API forma parte de la edicion

estandar de java (J2SE) y tambien de la edicion empresarial (J2EE).

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 metodos

de la clase para ver que se comporta como se espera. Es decir, en funcion de ciertos valores

de entrada se evaluan y luego se comprueba que la respuesta es la esperada, si la clase

cumple con la especificacion, entonces JUnit devolvera que el metodo de la clase paso exi-

tosamente la prueba, en caso de que el valor esperado sea diferente al que devolvio el

metodo durante la ejecucion, JUnit devolvera un fallo en el metodo correspondiente.

A traves de JUnit tambien se puede controlar que despues de hacer cambios en la

implementacion de una clase, se sigan cumpliendo las especificaciones.

El propio framework incluye formas de ver los resultados que pueden ser en modo texto

o grafico. Y en la actualidad las herramientas de desarrollo como NetBeans y Eclipse

cuentan con plugins que permiten que la generacion de las plantillas necesarias para la

creacion de las pruebas de una clase Java se realice de manera automatica, facilitando al

Page 36: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 4

programador enfocarse en la prueba y el resultado esperado, y dejando a la herramienta

la creacion de las clases que permiten coordinar las pruebas.

JSP Java Server Pages, es una tecnologıa Java que permite generar contenido dinamico

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ıa, y se compilan a clases

java la primera vez que se accede a cada pagina.

Las JSP’s permiten la utilizacion de codigo Java mediante scripts. Ademas, es posible

utilizar algunas acciones JSP predefinidas mediante etiquetas. Estas etiquetas pueden

ser enriquecidas mediante la utilizacion de librerıas de etiquetas externas, como las que

proporciona el framework struts, e incluso se pueden construır etiquetas personalizadas.

JSTL JavaServer Pages Standard Tag Library, es un componente de Java EE. Extiende

las JavaServer Pages (JSP) proporcionando librerıas de etiquetas con utilidades amplia-

mente utilizadas en el desarrollo de paginas web dinamicas.

Las diferentes librerıas de JSTL permiten realizar tareas comunes en el desarrollo de

la mayorıa de las aplicaciones web dinamicas, estas tareas son: iteradores para recorrer

colecciones de elementos y poder mostrarlos, etiquetas condicionales por si hay que escoger

entre varias opciones, y unas de las mas utilizadas, las etiquetas de internacionalizacion,

que facilitan en gran medida el proceso de cambiar facilmente el idioma de la aplicacion

ası como el formateo de datos para los diferentes paıses.

HTML HyperText Markup Language, es el lenguaje de marcado mas utilizado para

la construccion de paginas web. Es usado para describir la estructura y el contenido en

forma de texto, ası como para complementar el texto con objetos tales como imagenes,

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 estaran

rodeadas por corchetes angulares, ‘<etiqueta>‘. HTML tambien puede describir, hasta

Page 37: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 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 mas correcto es separar la apariencia y el comportamiento en diferentes

ficheros.

XML EXtensible Markup Language, es un metalenguaje extensible de etiquetas desa-

rrollado por el World Wide Web Consortium (W3C). Es una simplificacion y adaptacion

del SGML y permite definir la gramatica de lenguajes especı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 definicion son XHTML,

SVG, MathML.

XML no ha nacido solo para su aplicacion en Internet, sino que se propone como un

estandar para el intercambio de informacion estructurada entre diferentes plataformas. Se

puede usar en bases de datos, editores de texto, hojas de calculo y casi cualquier cosa

imaginable.

XML es una tecnologıa sencilla que tiene a su alrededor otras que la complementan

y la hacen mucho mas grande y con unas posibilidades mucho mayores. Tiene un papel

muy importante en la actualidad ya que permite la compatibilidad entre sistemas para

compartir la informacion de una manera segura, fiable y facil.

CSS Cascade Style Sheet, como su nombre indica son hojas de estilo, se utilizan para

definir la apariencia de una pagina web. En el documento HTML simplemente hay que

indicar en cada etiqueta un identificador que servira para luego establecer su apariencia a

partir del CSS.

CSS es una herramienta muy potente, dado que permite hacer cambios radicales en la

apariencia de una pagina sin tener que modificar en absoluto el codigo fuente. Permite

realizar casi cualquier cosa imaginable, desde cambiar tamanos, fuentes o colores, hasta la

posicion y el comportamientdo de los distintos elementos de una pagina.

Page 38: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 6

Apache Struts Apache Struts es un framework gratuito de codigo abierto para crear

aplicaciones web en Java de forma sencilla y rapida.

Las aplicaciones web difieren de las paginas web convencionales en que las aplicaciones

web pueden crear una respuesta dinamica. Muchos sitios web ofrecen solo las paginas

estaticas. Una aplicacion web puede interactuar con bases de datos o motores de la logica

de negocio para personalizar una respuesta.

En las aplicaciones basadas en JavaServer Pages, a veces se mezclan el codigo de acceso

a base de datos con codigo de diseno de la misma, y el codigo de control de flujo. En

la practica, nos encontramos con que a menos que estas preocupaciones estan separadas,

aplicaciones grandes son muy difıciles de mantener.

Una forma de separar las distintas partes de una aplicacion de software es utilizar una

arquitectura Modelo-Vista-Controlador (MVC). El modelo representa la empresa o de base

de datos de codigo, la vista representa el codigo de diseno de la pagina, y el Contralor

representa el codigo de la navegacion. La plataforma Struts esta disenada para ayudar a

los desarrolladores a crear aplicaciones web que utilizan una arquitectura MVC.

MySQL 5.0 Es un sistema de gestion de base de datos relacional, multihilo y multi-

usuario con mas de seis millones de instalaciones. Este sistema de gestion es uno de los mas

utilizados, porque, a parte de tener una licencia GPL, libre y gratuita, es facil de utilizar

en proyectos pequenos y actualmente es compatible con las tecnologıas mas importantes

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

Page 39: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 7

productos privativos deben comprar a la empresa una licencia especıfica que les permita

este uso. Esta desarrollado en su mayor parte en ANSI C.

Al contrario de proyectos como Apache, donde el software es desarrollado por una co-

munidad publica y el copyright del codigo esta en poder del autor individual, MySQL es

propietario y esta patrocinado por una empresa privada, que posee el copyright de la ma-

yor parte del codigo. Esto es lo que posibilita el esquema de licenciamiento anteriormente

mencionado. Ademas de la venta de licencias privativas, la companıa ofrece soporte y ser-

vicios. Para sus operaciones contratan trabajadores alrededor del mundo que colaboran

vıa Internet.

Apache Tomcat Apache Tomcat es una servidor web de codigo abierto, que sirve como

contenedor de paginas web para las tecnologıas Java Servlet y JavaServer Pages.

Apache Tomcat esta desarrollado en un entorno abierto y participativo por la companıa

Apache y publicado bajo la licencia Apache Software. Esta en continuo desarrollo y mante-

nimiento, y aunque hay diferentes productos no gratuitos que ofrecen mas funcionalidades,

para una aplicacion sencilla, es suficiente para ejecutarla.

IDE Eclipse Es un entorno de desarrollo integrado de codigo abierto multiplataforma

para desarrollar lo que el llama ‘Aplicaciones de Cliente Enriquecido‘, opuesto a las apli-

caciones ‘Cliente-liviano‘ basadas en navegadores. Esta plataforma, tıpicamente ha sido

usada para desarrollar entornos de desarrollo integrados (del ingles IDE), como el IDE de

Java llamado Java Development Toolkit (JDT) y el compilador (ECJ) que se entrega como

parte de Eclipse (y que son usados tambien para desarrollar el mismo Eclipse). Sin embar-

go, tambien se puede usar para otros tipos de aplicaciones cliente, y para otros lenguajes

de programacion. Ademas es un entorno que posibilita la utilizacion de plugins por lo que

se pueden anadir los plugins que se necesiten y ampliar de esa forma las funcionalidades

que se estimen oportunas.

Page 40: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 8

Eclipse es tambien una comunidad de usuarios, extendiendo constantemente las areas

de aplicacion cubiertas. Un ejemplo es el recientemente creado Eclipse Modeling Project,

cubriendo casi todas las areas de la Ingenierıa dirigida por el modelo.

Eclipse fue desarrollado originalmente por IBM como el sucesor de su familia de he-

rramientas para VisualAge. Eclipse sigue siendo desarrollado por la fundacion Eclipse,

una organizacion independiente sin animo de lucro que fomenta una comunidad de codigo

abierto y un conjunto de productos complementarios, capacidades y servicios.

PhpMyAdmin Es una herramienta de software libre escrito en PHP hecho con la in-

tencion de manejar la administracion de MySQL en la World Wide Web. PhpMyAdmin

es compatible con una amplia gama de operaciones con MySQL. Las operaciones mas

frecuentes son el apoyo de la interfaz de usuario (gestion de bases de datos, tablas, cam-

pos, relaciones, ındices, usuarios, permisos, etc) mientras que el usuario todavıa tiene la

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 aplicacion. Ası como la de realizar las diferentes

consultas que se puedan querer hacer.

Mozilla Firefox Es un navegador de Internet libre y de codigo abierto descendiente de

Mozilla Application Suite, desarrollado por la Corporacion Mozilla, la Fundacion Mozilla

y un gran numero de voluntarios externos.

Firefox es un navegador multiplataforma y esta disponible en varias versiones de Mi-

crosoft Windows, Mac OS X, GNU/Linux y algunos sistemas Unix. Su codigo fuente es

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 ano este na-

vegador gana nuevos adeptos, gracias, entre otras cosas, al licenciamiento como software

Page 41: Xesthproyecto

1.2. Herramientas y tecnologıas para la Implementacion 9

libre y a que cuenta con un gran numero de personas que consiguen sacar parches para

errores puntuales en un tiempo record gracias al eficaz sistema de reporte de errores.

Para visualizar paginas web, Firefox usa el motor de renderizado Gecko, que implementa

la mayorıa de los estandares web actuales ademas de otras funciones, algunas de las cuales

estan destinadas a anticipar probables adiciones a los estandares web.

Incluye navegacion por pestanas, corrector ortografico, busqueda progresiva, marcadores

dinamicos, un administrador de descargas y un sistema de busqueda integrado que utiliza

el motor de busqueda que desee el usuario. Ademas se pueden anadir funciones a traves

de complementos desarrolladas por terceros, muy util a la hora de comprobar aplicaciones

web o de realizar el diseno de la interfaz de usuario de estas.

Apache Maven 2 Maven 2 es una herramienta para la gestion de proyectos software que

proporciona soluciones a tareas comunes a todos los proyectos desde la compilacion inicial

hasta la distribucion e instalacion en los sistemas finales. Maven genera una estructura de

directorios y ficheros que sirve de estructura base. Esta estructura de directorios es estandar

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 aplicacion, ya que siempre sabra donde puede encontrar las cosas.

Maven utiliza un fichero XML conocido como Project Object Model (POM) para descri-

bir el proyecto de software a construir, sus dependencias de otros modulos y componentes

externo, y el orden de construccion de los elementos. Esta es una caracterı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 necesitara y Maven ya

se encarga de tenerlas preparadas, siempre y cuando disponga de conexion a Internet, ya

que le hara falta en caso de que tenga que descargar las dependencias que necesita.

Page 42: Xesthproyecto

1.3. Herramientas y tecnologıas para la Documentacion 10

1.3. Herramientas y tecnologıas para la Documentacion

LATEX Es un lenguaje de marcado para documentos, y un sistema de preparacion de

documentos, formado por un gran conjunto de macros de TEX, escritas inicialmente por

Leslie Lamport (LamportTeX) en 1984, con la intencion de facilitar el uso del lenguaje de

composicion tipografica creado por Donald Knuth. Es muy utilizado para la composicion

de artıculos academicos, tesis y libros tecnicos, dado que la calidad tipografica de los

documentos realizados con LATEX es comparable a la de una editorial cientıfica de primera

lınea. LATEX es software libre bajo licencia libre.

Kile Es una herramienta para trabajar con LATEX en GNU/Linux. Facilita entre otras

cosas las labores de compilacion LATEX y de generacion de documentos. Ademas propor-

ciona caracterısticas algunas tıpicas de los entornos de edicion de texto ‘wysiwyg‘ como

Microsoft Word o OpenOffice Writer. Los comandos basicos para la edicion de un tex-

to LATEX no hay que saberselos, ya que Kile proporciona un entorno que facilita mucho

el aspecto de escribir los comandos, proporcionando en forma de botones aquellos mas

utilidados. A continuacion se senalan algunas cuestiones de configuracion que resulta util

conocer.

Configurar bien la codificacion de la pagina, ya que, salvo que se le indique lo contrario,

Kile utiliza la codificacion que el sistema GNU/Linux tiene activada por defecto. En las

configuraciones modernas la codificacion frecuentemente es utf-8 (unicode). Sin embargo lo

mas habitual en los documentos LATEX que utilizamos es usar latin1, que corresponde con

la codificacion iso 8859-1 o iso 8859-15 si los textos en espanol van a utilizar algun sımbolo

especial. Si al abrir un archivo aparecen caracteres raros esto indica una configuracion de

codificacion de Kile no es la correcta y habra que modificarla.

Planner Aplicacion software libre para realizar planificanion de proyectos, utililzada

para la planificacion del proyecto actual y la evaluacion de costes. Entre sus funcionalidades

Page 43: Xesthproyecto

1.3. Herramientas y tecnologıas para la Documentacion 11

se puede observar la del calculo del coste asociado a cada una de las tareas, realizacion de

diagramas de Gantt para seguir la realizacion del proyecto.

El unico inconveniente de esta aplicacion es que no exporta a ningun formato de imagen

los diagramas finales.

GIMP Es un editor de imagenes software libre que permite crear y modificar imagenes de

distintos formatos y exportarlas finalmente a practicamente cualquier formato de imagen.

Este editor tiene unas prestaciones parecidas al programa Photoshop de Adobe pero con

las ventajas de que no hay que pagar una licencia por el, es comodo de usar y, auque tiene

una curva de aprendizaje larga, es muy rapido de utilizar una vez que se sabe manejar.

Page 44: Xesthproyecto
Page 45: Xesthproyecto

Capıtulo 2

Estado actual de las tecnologıas

utilizadas

Antes de desarrollar cualquier proyecto software lo primero que hay que hacer es iden-

tificar todas las tecnologıas que se utilizaran en el mismo. Para ello un desarrollador se

sirve de su experiencia con las distintas herramientas y de los requisitos que tendra que

cumplir la aplicacion que va a desarrolar, ya que algunas tecnologıas no permitiran que

estos se cumplan.

En un primer lugar para este proyecto se descartaran automaticamente todas aquellas

tecnologıas que impidan licenciar el sistema final como software libre, siendo basicamente

todas aquellas que esten licenciadas bajo una licencia privativa. En ciertas situaciones

sera complicado encontrar aplicaciones, y tecnologıas libres equivalentes a las tecnologıas

privativas mas comunes, ademas de ser una dificultad el encontrar algun software, tambien

influira en el tiempo de desarrollo del proyecto, ya que habra que aprender a manejar las

tecnologıas elegidas.

Cuando se quiere desarrollar una aplicacion web lo primero que hay que identificar es

la plataforma a utilizar, en este caso J2EE, ya se sabıa de antemano porque era uno de

los requisitos del proyecto, pero aparte de J2EE hay otras alternativas como pueden ser la

13

Page 46: Xesthproyecto

14

plataforma .NET o PHP, cualquiera de ellas se podrıa utilizar. En el caso de J2EE la curva

de aprendizaje es muy larga, entre otras cosas porque se necesita saber utilizar un unico

lenguaje de programacion, pero a parte de eso se necesitan aprender como funcionan las

diferentes tecnologıas que se utilizaran conjuntamente a la hora de desarrollar el proyecto.

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 estan controladas y gestionadas

por Microsoft.

Aunque la tecnologıa a utilizar no estuviera previamente determinada, .NET no se podrıa

utilizar debido a que su entorno de desarrollo integrado es propietario y de un coste muy

elevado que harıa inviable el proyecto, frente a los entornos de desarrollo que existen en el

mercado para trabajar con J2EE entre los que destaca Eclipse, considerado por muchos

el mejor entorno de desarrollo integrado libre del mercado. Ademas hay otros aspectos de

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 solo se puede montar sobre plataformas de Microsoft. Del mismo modo .NET

solo cuenta con servidores comerciales de pago mientras que J2EE funciona tanto sobre

servidores de pago como libres.

Por otra parte dada la naturaleza del proyecto y a que se licenciara como software libre

para que otros desarrolladores puedan agregar nuevas mejoras, este debe ser facilmente

escalable, por eso tambien en este caso de adapta perfectamente J2EE que permite gran es-

calabilidad por si en el futuro se desea integrar esta aplicacion con otras para proporcionar

mas funcionalidades.

J2EE nos es la opcion mas rapida del mercado, ya que en este aspecto otras tecnologıas

como PHP no tienen competidor, pero es lo suficientemente rapido para dar soporte a las

necesidades de la aplicacion final.

Page 47: Xesthproyecto

15

Se necesita tambien un gestor de bases de datos para el proyecto y para ello habra que

tener en cuenta de igual forma que sea una tecnologıa libre, por lo que quedan descarta-

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 mas o menos las mis-

mas prestaciones, se utilizara MySQL dada la familiaridad que se tiene, a que tiene una

comunidad de usuarios bien organizada y al bajo coste debido a su licencia libre.

Page 48: Xesthproyecto
Page 49: Xesthproyecto

Capıtulo 3

Estudio de viabilidad

Obviamente antes de realizar el proyecto que aquı se esta detallando, se estudio si era

viable realizarlo y terminarlo con exito en el tiempo previsto, puesto que, al ser un proyecto

academico para dar fin a la formacion que se ha estado recibiendo, la fecha lımite serıa la

que marcaran las convocatorias para la entrega del proyecto. Si el proyecto no fuese viable

no se podrıa realizar porque no se tendrıa la garantıa de terminarlo.

A parte del tiempo del que se dispone para la realizacion de esta aplicacion, tambien es

un factor decisivo para estudiar la viabilidad del mismo, el coste, que debera ser el mınimo

posible.

Este proyecto no solo valdra para terminar los estudios, sino que se hara de tal forma

que sea facilmente ampliable para que en el futuro se pueda adaptar para una aplicacion

empresarial real con muy poco esfuerzo y haciendo los mınimos cambios posibles. Para

posibilitar la realizacion de futuros cambios, en la realizacion del diseno de la aplicacion ya

se han tenido en cuenta posibles puntos de amplicacion. De esta forma se podrıa adaptar

la aplicacion para venderla, y con muy pocos cambios sacarle mucha rentabilidad a la

aplicacion web.

Por otro lado como la realizacion del proyecto solo se hara por parte de una persona,

este no se hara demasiado extenso para que sea viable realizarlo en 4 o 6 meses.

17

Page 50: Xesthproyecto

18

Para que cualquier proyecto sea rentable realizarlo hay que tener en cuenta el coste en

cuanto a tiempo de desarrollo y tambien el coste derivado de la utilizacion de las distintas

tecnologıas. Por esa razon para que la realizacion del proyecto saliese rentable, se decide

utilizar solamente software libre y gratuito, gracias a esto tambien cabe la posibilidad de

licenciar la aplicacion final como software libre.

A continuacion se detallan algunas de las tecnologıas y herramientas software conside-

radas y finalmente utilizadas, ası como su coste asociado.

Herramienta Descripcion Cantidad Precio (e)

MySQL Gestor de base de datos relacionalutilizado para almacenar los datosde la aplicacion

1 0.00

IDE Eclipse Entorno de programacion integradoutilizado para realizar la programa-cion de la aplicacion

1 0.00

Apache Tomcat Servidor de Aplicaciones Web utili-zado contener la aplicacion

1 0.00

DIA Editor de diagramas utilizados uti-lizados para realizar los diagramasdel modelo Entidad-Relacion de labase de datos

1 0.00

Argo UML Editor de diagramas UML utili-zados para realizar los diagramasUML del modelo de la aplicacion

1 0.00

PhpMyAdmin Aplicacion utilizada para gestionary monitorizar las bases de datos uti-lizadas

1 0.00

Kile Editor de textos paraLATEXutilizado para realizar to-da la documentacion necesaria parala aplicacion

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ıas utili-

zadas, el coste total de todas es de 0.00e, por lo que el coste final sera igual al coste del

tiempo empleado en el desarrollo de la aplicacion. Esto cambiarıa si se utilizasen herra-

Page 51: Xesthproyecto

19

mientas y tecnologıas de pago, porque solo por el coste de las licencias, el proyecto que se

desea realizar serıa totalmente inviable para realizar como proyecto fin de carrera.

Page 52: Xesthproyecto
Page 53: Xesthproyecto

Capıtulo 4

Introduccion al desarrollo

realizado

4.1. El Proceso Unificado

Para realizar este proyecto se utiliza una metodologıa basada en iteraciones, donde en

cada una de ellas se consigue implementar un conjunto de funcionalidades de la aplicacion,

casos de uso, y ası al terminar la utima iteracion se tiene un sofware que implementa todos

los casos de uso.

En cada una de las iteraciones se realizara analisis, diseno, implementacion y pruebas.

Para realizar estas iteraciones se utiliza la metodologıa que define el Proceso Unificado,

(UP, Unified Process). Este proceso de desarrollo, acompanado del leguaje de modelado

UML (Unified Modelling Languaje) son, conjuntamente, la metodologıa que mas se utiliza

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 mas conocido del Proceso Unificado es el Proceso

21

Page 54: Xesthproyecto

4.1. El Proceso Unificado 22

Unificado de Rational que es un marca registrada de IBM, pero hay otros muchos refina-

mientos: Agile UP, Open UP, etc.

El UP esta compuesto por cuatro fases denominadas Concepcion, Elaboracion, Cons-

truccion y Transicion, donde cada una de estas fases se divide en iteraciones. Cada una

de las iteraciones ofrece como resultado un incremento del producto que anade o mejora

funcionalidades del sistema.

Cada iteracion se divide en disciplinas como las que se definıan en el ciclo de vida

clasico: Analisis de requisitos, Diseno, Implementacion, Pruebas, etc. Pero, aunque todas

las iteraciones incluyen trabajo en casi todas las disciplinas, cada una de ellas se centra

mas en una iteracion u otra. Este enfasis en cada iteracion se puede observar en el grafico

de la figura 4.1.

Figura 4.1: Grafico del Proceso Unificado

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 iteracion. Estos contenidos son los recogidos en un cada uno de los conjuntos

Page 55: Xesthproyecto

4.1. El Proceso Unificado 23

de casos de uso o escenarios, de forma que cada iteracion pase a traves de todas las

disciplinas: diseno, implementacion, etc. Ademas, siguiendo este proceso de desarrollo, hay

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 continuacion se detalla lo que tiene lugar en las distintas fases del Proceso Unificado:

Fase de Concepcion

Esta fase es la mas pequena del proyecto, en ella se deben establer el ambito del

proyecto y una justificacion de por que se realiza.

Ademas es en este momento cuando se esbozan los casos de uso y los requisitos

principales por los cuales se dirigiran las cuestiones de diseno del proyecto. Por otro

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

continuacion se debe preparar un plan para el proyecto y una estimacion de los costes

que este conllevara.

Fase de Elaboracion

Es la fase en la cual se capturan la mayorıa de los requisitos del sistema, identificando

tambien los riesgos y estableciendo la arquitectura general del sistema.

Ademas se debe implementar una Base de Arquitectura Ejecutable para demostrar

que el sistema final soportara los aspectos claves de funcionalidad establecidos y

comprobar que tiene un rendimiento, escalabilidad y coste adecuados.

Fase de Construccion

Es la mas larga del proyecto, donde se construye el sistema en base a lo especificado

en la fase de elaboracion. Esta fase se divide en una serie de iteraciones, y en cada

Page 56: Xesthproyecto

4.2. El Proceso Unificado en este Proyecto 24

una de ellas se implementa un conjunto de las funcionalidades, terminando cada una

con una version completa de la aplicacion final.

Fase de Transicion

Esta es la fase en la que se despliega la aplicacion para el usuario final, y recogiendo

las impersiones de estos para incorporar refinamientos al sistema en sucesivas itera-

ciones, esta fase tambien incluye el entrenamiento en la utilizacion del sistema por

parte de los usuarios.

4.2. El Proceso Unificado en este Proyecto

A continuacion se vera como se aplico el Proceso Unificado en el desarrollo de este

proyecto, para ello se iran indicando las diferentes fases por las que se fue pasando y las

iteraciones que se realizaron en cada una de ellas con una descripcion de lo que se hizo.

Fase de Concepcion

1. Iteracion 1

En esta iteracion se hizo un analisis de las funcionalidades que deberıa con-

templar la aplicacion, estableciendo textualmente los requisitos principales del

sistema.

A partir de este analisis de requisitos se realizo el diseno Entidad Relacion de

la base de datos que necesitara la aplicacion, para luego realizar el modelo rela-

cional. A continuacion se implementa la base de datos en base a lo especificado

en el modelo relacional.

Ademas en este momento se vio que probablemente serıa un riesgo a solventar

que el driver JDBC, que posteriormente se utilizara para conectarse a la base

de datos, funcionase correctamente. Se detecto en este momento un mal funcio-

namiento de la conexion con la base de datos y se resolvio despues de consultar

la documentacion especıfica del manejador JDBC.

Page 57: Xesthproyecto

4.2. El Proceso Unificado en este Proyecto 25

Fase de Elaboracion

1. Iteracion 1

En esta iteracion se realiza un analisis de requisitos mas exhaustivo, realizando

el modelo de casos de uso. A partir de este analisis de requisitos se refina el

diseno de la base de datos y se implementan los cambios realizados.

Se disena en este momento como sera la capa modelo, los DAO y las Fachadas

que se necesitaran. A partir de este diseno se implementa la capa de acceso a

base de datos (DAO) y alguna de las fachadas, tambien se hacen las pruebas

de unidad correspondientes a estas implementaciones.

Ademas se hacen pruebas para ver como funciona la tecnologıa struts que se

utilizara para implementar la capa controladora de la aplicacion web.

Fase de Construccion

1. Iteracion 1

En esta iteracion se refinan pequenos detalles de los requisitos y se disena la

capa controladora y la vista.

Es ahora cuando se implementa un subconjunto completo de casos de uso, en

este caso el referido a la gestion de usuarios. Se implementa 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 autentificar al usuario en la aplica-

cion, darlo de alta, etc, para lo que tambien hay que implementar el mecanismo

para mantener las sesiones.

Para terminar con esta iteracion y conseguir una version funcional del sistema

se prueba que se realicen correctamente los requisitos especificados en los casos

de uso.

Iteracion 2

Page 58: Xesthproyecto

4.2. El Proceso Unificado en este Proyecto 26

En este momento se refina el diseno de las fachadas que se van a implementar de

forma que se ajuste exactamente a lo que se desea. Ademas se disena la estructura

general del sistema de ofertas con el que se iteractuara a la hora de realizar las

facturas.

En este momento se implementan otros dos subconjuntos completos de casos de uso,

en este caso los referidos a la gestion de reservas y habitaciones. Se implementa

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 realizacion de las reservas.

Para terminar con esta iteracion y conseguir una version funcional del sistema se

prueba que se realicen correctamente los requisitos especificados en los casos de uso.

Iteracion 3

En este momento se refina el diseno del sistema de las ofertas para que se ajuste

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 gestion de facturas y ofertas. Se implementa 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 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 iteracion y conseguir una version funcional del sistema se

prueba que se realicen correctamente los requisitos especificados en los casos de uso,

prestando especial atencion al sistema de ofertas, ya que la unica forma de probarlo

es en este momento, debido a la dificultad de realizar pruebas de unidad de cada

uno de los metodos que forman sus clases.

Fase de Transicion

Page 59: Xesthproyecto

4.2. El Proceso Unificado en este Proyecto 27

Esta fase del Proceso Unificado no es necesaria realizarla para la realizacion del pro-

yecto debido a que en este caso solo valdra para evaluar los conocimientos adquiridos

durantes los estudios realizados. Si este proyecto tuviese que ser adaptado para su

comercializacion, serıa en esta fase cuando se desplegarıa ante el usuario final para

que informase si todo esta como se habıa pedido y cuando se ensenarıa al usuario a

utilizar la aplicacion.

Page 60: Xesthproyecto
Page 61: Xesthproyecto

Capıtulo 5

Requisitos del Sistema

5.1. Introduccion

Antes de comenzar cualquier proyecto de desarrollo de software, lo primero que hay que

hacer es un analisis de requisitos del sistema, es decir, hay que conocer las caracterısticas

que debe tener el sistema.

Las caracterısticas de una aplicacion las determinan el cliente que la solicita y el usuario

final que lo va a utilizar. En nuestro caso necesitamos una aplicacion que permita gestionar

las reservas de un hotel y demas partes del mismo, de una forma sencilla. El sistema a

desarrollar esta orientado a las pequenas y medianas empresas hoteleras, por lo que el

coste del producto lo hay que reducir lo maximo posible.

En la actualidad la gran mayorıa de pequenos hoteles o similares realizan sus tareas de

una forma manual, o utilizando numerosos productos software. La gestion de las reservas

se suele hacer por telefono o en persona en el lugar donde se encuentre el establecimiento,

anotando las mismas en un libro de reservas ya sea, en formato papel o digital. Ademas

necesitan un software especial para gestionar el proceso de facturacion del hotel, y no

tienen manera de gestionar de forma automatica y eficaz, todas las ofertas que puedan, o

quieran, tener a disposicion del consumidor.

29

Page 62: Xesthproyecto

5.1. Introduccion 30

Las grandes firmas hoteleras y las cooperativas de varios hoteles no tienen estos proble-

mas, 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 solucion lo mas generica posible

para todas aquellas pequenas empresas a las cuales un producto como este les facilitarıa

muchısimo las cosas a la hora de gestionar sus modestos negocios, ademas de proporcionar

la opcion de gestionar un sitio web propio que este totalmente integrado, dando, entre

otras cosas, la opcion de hacer reservas y consultas on-line.

Una de las cosas mas importantes es que este sistema se licenciara como software libre

bajo una licencia GPL (General Public License), de modo que todo aquel que lo necesite

pueda acceder a este software de manera totalmente gratuita.

El desarrollo de este producto software esta pensado para que, en caso necesario, sea

facilmente ampliable, configurable y ajustable, para adaptarse a las necesidades del usuario

final. Esta aplicacion contiene las funcionalidades basicas que un establecimiento hotelero

pueda necesitar en su dıa a dıa, pero esta orientado a que en cualquier momento se puedan

realizar cambios de forma sencilla y sin alterar su estructura general.

El funcionamiento basico del sistema final tiene que dar soporte para dar de alta a

nuevos clientes, ası como para la realizacion de reservas por parte de los clientes a traves

de internet y en el establecimiento del hotel por parte del recepcionista, tambien dara la

posibilidad de que el administrador gestione todas las partes mas crıticas del negocio,

como son las habitaciones y sus precios, o la publicacion de nuevas ofertas para que esten

a disposicion de los usuarios.

Cuando un nuevo usuario acceda a la aplicacion a traves de internet se le proporcionara la

oportunidad de darse de alta, o si ya lo esta, de acceder al sistema. Para ello se le pediran

sus datos personales, los cuales seran utilizados posteriormente a la hora de realizar las

facturas a nombre del cliente. Si por el contrario el alta del nuevo cliente la realiza el

recepcionista, se le pediran los mismos datos a excepcion del nombre de usuario que desea

Page 63: Xesthproyecto

5.1. Introduccion 31

y su contrasena, ya que esos datos se los tendra que pedir explıcitamente el cliente al

recepcionista.

Un cliente, una vez registrado y autentificado en el sistema tendra, la posibilidad de

hacer una reserva para los dıas que desee. Para la realizacion de una reserva simplemente

sera necesario que el cliente este registrado, pero esta reserva no sera una reserva real hasta

que el cliente la pague, para lo cual el administrador del hotel tendra que dar un plazo,

y si el cliente no paga la reserva dentro de ese plazo esta sera cancelada. De este modo

se pueden evitar perdidas derivadas de intentos de sabotaje por parte de algun usuario

malintencionado.

Una vez realizada la misma, se le comunica al cliente el numero de reserva que de-

bera buscar para pagar. A partir de ese momento el cliente puede consultar la reserva

realizada y modificarla si lo desea, o ver la factura y pagarla o cancelarla. La factura que

ve el cliente se genera automaticament; para ello el sistema debera utilizar algun algoritmo

especial que permite aplicar las ofertas pertinentes.

El sistema de ofertas es quiza una de las partes de la aplicacion mas complicada de resol-

ver. Una oferta va a pertenecer a un tipo de ofertas; estos tipos los definira el administrador

(obviamente de cada tipo de oferta solo se podra aplicar una oferta).

Hasta aquı la parte sencilla, este sistema tambien permitira acumular ofertas de forma

que se puedan aplicar varios descuentos de ofertas distintas sobre el importe inicial, y

dejara al administrador especificar mediante reglas altamente configurables, el conjunto

de clientes o aquellas situaciones especıficas en las cuales se podra aplicar una oferta; por

lo tanto, otro problema a solventar sera la definicion de dicho lenguaje de reglas.

Como acabamos de mencionar, de cada tipo de oferta solamente una se podra aplicar,

pero ademas los tipos tendran incompatibilidades entre sı, relaciones mediante las cuales

se definira que ofertas no se pueden aplicar conjuntamente. La aplicacion debe resolver de

forma rapida y eficaz esta problematica, ya que a la hora de calcular la mejor oferta que

Page 64: Xesthproyecto

5.2. Actores 32

se le puede ofrecer a un cliente sobre una factura, tendra que calcular cual es el conjunto

de ofertas que a este le proporcionara un mayor descuento.

En las siguientes secciones se veran en detalle todas las situaciones que el sistema de-

bera contemplar y resolver, y todos los usuarios que interactuaran con la aplicacion.

Para la definicion de las funcionalidades del sistema se empleara notacion UML (Unified

Modelling Language) especificando los usuarios del sistema y todos los que interactuan

con el (actores), y los comportamientos del mismo ante las peticiones de los actores (casos

de uso).

Las funcionalidades basicas de este producto se definiran en cojuntos de casos de uso, a

traves de los cuales se detallara el funcionamiento de la aplicacion.

5.2. Actores

Como se acaba de mencionar, un actor es alguien o algo que intercambia informacion

con el sistema, bien sea un usuario u otro sistema. Varios usuarios se pueden representar

como un solo actor para el sistema y viceversa, un mismo usuario puede ser representado

por varios actores.

Se pueden distinguir varios tipos de actores, de los cuales los mas importantes son:

Los actores primarios y los de soporte. Los actores primarios son aquellos que utilizan

el sistema para alcanzar sus objetivos y a traves de los cuales se pueden identificar los

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 aplicacion y no se autentifica o se registra. Este

usuario puede hacer consultas de precios, ofertas y demas, pero no podra realizar

Page 65: Xesthproyecto

5.3. Casos de Uso 33

ningua reserva. Este tipo de usuario tiene la opcion de autentificarse o de registrarse

en el sistema.

Cliente Es aquel usuario que se ha autentificado, tiene la posibilidad de hacer las mis-

mas operaciones que una Persona, pero ademas tambien puede realizar reservas de

habitaciones, hacer consultas sobre sus reservas y facturas, y pagar o cancelar las

reservas que desee. Entre otras cosas este usuario tambien puede actualizar su perfil

o darse de baja en el sistema.

Recepcionista Es el empleado del hotel que se encarga de la recepcion del mismo, este

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 ningun otro usuario.

Como el Cliente va a poder hacer las mismas operaciones que la Persona, esto significa

que entre los dos constituyen una jerarquıa de usuarios.

Pero ademas la aplicacion necesita un indispensable actor de soporte:

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 operacion. Un caso

de uso especifica claramente lo que hace una operacion desde el punto de vista del actor

que la realiza. En el apareceran exclusivamente aquellos detalles que son relevantes para

el actor.

Page 66: Xesthproyecto

5.3. Casos de Uso 34

En primer lugar se expecificaran los distintos casos de uso siguiendo las especificaciones

que proporciona el proceso de desarrollo unificado, que es el que se esta siguiendo en la

elaboracion de este proyecto. Estas especificaciones indican que el detallado de un caso de

uso debe contener la siguiente informacion: actores, precondiciones, postcondiciones, flujo

basico y flujo alternativo.

Los actores son los usuarios implicados en el caso de uso en cuestion. Las precondiciones

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, quedara el sistema una vez termine la ejecucion del caso

de uso.

Aunque lo mas importante para detallar un caso de uso es indicar cual va a ser su flujo

basico de eventos y cual su flujo alternativo. El flujo basico de eventos indica los eventos

que se han de realizar para que el caso de uso termine exitosamente. El flujo alternativo

es aquel flujo de eventos que se seguira en caso de que algun fallo ocurra durante el flujo

basico del mismo.

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 estan contextualmente relacionados entre sı.

5.3.1. Casos de Uso de Gestion de Usuarios Web

Estos casos de uso son todos aquellos relacionados con la gestion de los Usuarios del

sistema, registro, autentificacion, etc. Se puede ver el diagrama correspondiente en la figura

5.1 de la pagina 78.

1. Autenticarse

Actores Primarios: Cliente, Recepcionista, Administrador.

Page 67: Xesthproyecto

5.3. Casos de Uso 35

Descripcion: Permite a una persona entrar en el sistema.

Precondiciones: La persona aun no esta autenticada en el sistema.

Postcondiciones: La persona pasa a estar autenticada en el sistema.

Flujo basico:

1 La persona quiere autenticarse en el sistema.

2 El sistema pide a la persona que introduzca su nombre de usuario y su con-

trasena.

3 La persona introduce su nombre de usuario y su contrasena.

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 contrasena o ambos.

4.2 El sistema indica que tiene que indicar el nombre de usuario y contrasena.

4.3 Se vuelve al evento 2 del flujo basico.

5.1 El nombre de usuario o contrasena son incorrectos.

5.2 El sistema se lo indica a la persona y le da la opcion de registrarse.

5.3 Se vuelve al paso 2.

2. Salir del sistema

Actores Primarios: Cliente, Recepcionista, Administrador

Descripcion: Permite a un cliente dejar de estar autenticado en el sistema.

Precondiciones: El cliente esta autenticado en el sistema.

Page 68: Xesthproyecto

5.3. Casos de Uso 36

Postcondiciones: El cliente deja de estar autenticado en el sistema.

Flujo basico:

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 peticion y el cliente deja de estar autenticado en la

aplicacion.

Flujo alternativo:

*.1 En cualquier momento la persona tiene la posibilidad de cancelar el proceso.

3. Dar de Alta Usuario

Actores Primarios: Persona

Descripcion: Permite a una nueva persona que entra en el portal Web del hotel darse de alta

como usuario del mismo.

Precondiciones: La persona no esta autenticada en el sistema.

Postcondiciones: La persona pasa a estar autenticada en el sistema y se registra como nuevo

usuario de este.

Flujo basico:

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)

Page 69: Xesthproyecto

5.3. Casos de Uso 37

• Apellidos (obligatorio)

• DNI o pasaporte (obligatorio)

• Fecha de Nacimiento (obligatorio)

• Direccion completa (obligatorio)

• Paıs (obligatorio)

• Direccion de e-mail (obligatorio)

• Telefono1 (opcional)

• Telefono2 (opcional)

• Nombre de Usuario (obligatorio)

• Contrasena (obligatorio)

• Confirmacion de contrasena (obligatorio)

3 La persona introduce los datos solicitados.

4 La persona confirma que desea darse de alta.

5 El sistema procesa la informacion del nuevo cliente.

6 La persona pasa a estar dada de alta como cliente.

7 El sistema autentica al cliente en la aplicacion.

8 El cliente esta autenticado en el sistema.

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 contra-

senas no coinciden.

4.1.2 El sistema indica que tiene que introducir los datos obligatorios y se

vuelve al evento 2 del flujo basico.

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 esta dada de alta.

Page 70: Xesthproyecto

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

Descripcion: Permite a un cliente modificar los datos con los que se dio de alta como usuario

del sistema.

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: Los datos del cliente estan actualizados.

Flujo basico:

1 El cliente quiere midificar los datos con los que se dio de alta en el sistema.

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)

• Direccion completa (obligatorio)

• Paıs (obligatorio)

• Direccion de e-mail (obligatorio)

• Telefono1 (opcional)

• Telefono2 (opcional)

• Contrasena (obligatorio)

• Confirmacion de contrasena (obligatorio)

3 El cliente modifica los datos que quiere.

Page 71: Xesthproyecto

5.3. Casos de Uso 39

4 El cliente confirma que desea actualizar sus datos.

5 El sistema procesa la actualizacion de los datos del cliente.

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 contrasenas

no coinciden.

4.2 El sistema indica que tiene que introducir los datos obligatorios y se vuelve

al evento 2 del flujo basico.

5. Consultar datos de Usuario

Actores Primarios: Cliente, Recepcionista, Administrador

Descripcion: Permite a un cliente consultar los datos con los que se dio de alta en el sistema.

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

1 El cliente quiere consultar los datos con los que se dio de alta en el sistema.

2 El sistema muestra al cliente sus datos personales.

6. Dar de baja Usuario

Actores Primarios: Cliente

Descripcion: Permite a un un cliente darse de baja como usuario del sistema.

Page 72: Xesthproyecto

5.3. Casos de Uso 40

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: El cliente deja de estar autenticado en el sistema y deja de existir como usuario

de la aplicacion.

Flujo basico:

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 aplicacion.

Flujo alternativo:

*.1 En cualquier momento el cliente tiene la posibilidad de cancelar el proceso.

5.3.2. Casos de Uso de Gestion de Reservas Web

Los Casos de Uso que aquı se detallan son todos los relacionados con la gestion de las

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 pagina 79.

7. Hacer reserva web

Actores Primarios: Cliente

Descripcion: Permite a un cliente realizar una reserva de una o varias habitaciones para un

dıa determinado.

Precondiciones: El cliente esta autenticado en el sistema.

Page 73: Xesthproyecto

5.3. Casos de Uso 41

Postcondiciones: La reserva queda realizada a espera de que el cliente la pague.

Flujo basico:

1 El cliente quiere realizar una reserva de habitacion.

2 La aplicacion pide al cliente que indique el tipo de habitacion que desea

reserva, el dıa que llega, el dıa de salida, y la cantidad de habitaciones de

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 habitacion

para los dıas indicados.

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 numero de reserva para que la pueda localizar.

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 basico.

4.2.1 El cliente ha introducido una fecha de llegada o de salida erronea.

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 habitacion.

4.4.2 El sistema procesa la reserva.

4.4.3 Se vuelve al paso 2 para realizar la siguiente reserva.

Page 74: Xesthproyecto

5.3. Casos de Uso 42

8. Consultar reservas web

Actores Primarios: Cliente

Descripcion: Permite a un cliente consultar las reservas que ha realizado desde que es cliente

del hotel, se podran ver las reservas pagadas, las canceladas y las que estan aun

pendientes de pago.

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

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

Descripcion: Permite a un cliente modificar una reserva realizada

Precondiciones: El cliente esta autenticado en el sistema, y la reserva no esta pagada ni cance-

lada.

Postcondiciones: La reserva queda modificada a espera de que el cliente la pague.

Flujo basico:

1 El cliente quiere modificar una reserva de habitaciones.

2 El cliente indica que desea anadir una nueva reserva de habitacion.

Page 75: Xesthproyecto

5.3. Casos de Uso 43

3 La aplicacion pide al cliente que indique el tipo de habitacion que desea

reserva, el dıa que llega, el dıa de salida, y la cantidad de habitaciones de

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 habitacion

para los dıas indicados.

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 habitacion.

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 eliminacion de la lınea de reserva.

2.5 Se pasa al paso 2 del flujo basico.

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 basico.

5.2.1 El cliente ha introducido una fecha de llegada o de salida erronea.

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.

Page 76: Xesthproyecto

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

Descripcion: Permite a un cliente consultar la factura de cualquier reserva que haya realizado

desde que es cliente del hotel, se podran ver las facturas pagadas, las canceladas

y las que estan aun pendientes de pago.

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

1 El cliente quiere consultar una factura de una reserva que ha realizado.

2 El sistema pide al cliente que indique el numero de reserva para la factura

que desea consultar.

3 El cliente indica el numero de reserva deseado.

4 El sistema muestra al cliente la factura de la reserva solitada. En el caso

de que la factura ya este pagada o cancelada muestra el importe que ha

pagado y si la factura esta pendiente de pago muestra el total que debe

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.

Page 77: Xesthproyecto

5.3. Casos de Uso 45

11. Cancelar reserva web

Actores Primarios: Cliente

Descripcion: Permite a un cliente cancelar cualquier reserva que haya realizado y aun no dis-

frutado, si la factura estuviese pagada se le devuelve un porcentaje del importe,

dependiendo de la antelacion con la que la cancele.

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: La reserva queda cancelada.

Flujo basico:

1 El cliente quiere cancelar una reserva que ha realizado.

2 El sistema pide al cliente que indique el numero de reserva que desea cancelar.

3 El cliente indica el numero de reserva deseado.

4 El sistema pide al cliente la confirmacion de que quiere cancelarlas.

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 numero de reserva que ya habıa sido cancelada o dis-

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

Page 78: Xesthproyecto

5.3. Casos de Uso 46

Actores Primarios: Cliente

Actores de Soporte: Entidad Financiera

Descripcion: Permite a un cliente pagar la factura de una reserva.

Precondiciones: El cliente esta autenticado en el sistema.

Postcondiciones: La factura de la reserva esta pendiente de pago y no esta cancelada.

Flujo basico:

1 El cliente quiere pagar la factura de una reserva que ha realizado.

2 El sistema pide al cliente que indique el numero de reserva que desea pagar.

3 El cliente indica el numero de reserva deseado.

4 El sistema muestra al cliente la factura de la reserva y le pide la confirmacion

de que quiere pagarla.

5 El cliente lo confirma.

6 El sistema marca la factura como en proceso de pago y envıa los datos del

pago a la entidad financiera.

7 El cliente y la entidad financiera gestionan el pago de la factura.

8 La entidad financiera envıa al sistema la confirmacion de pago de la factura.

9 El sistema comprueba la confirmacion.

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 numero de reserva que ya habıa sido pagado o que ya

esta en proceso de pago.

3.2 Se le muestra un error al cliente y se termina el proceso sin que se pague

la factura de la reserva.

Page 79: Xesthproyecto

5.3. Casos de Uso 47

8.1 La entidad financiera no envıa la confirmacion de pago de la factura.

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 Gestion de Clientes

Estos casos de uso son todos aquellos relacionados con la gestion de los Clientes,

en la recepcion del hotel, registro de nuevos clientes, consulta y modificacion de sus

datos, etc. Se puede ver el diagrama correspondiente en la figura 5.3 de la pagina 80.

13. Buscar Cliente

Actores Primarios: Recepcionista

Descripcion: Permite al recepcionista buscar a un cliente para trabajar con el.

Precondiciones: El recepcionista esta autenticado en el sistema.

Postcondiciones: El recepcionista sigue siendo el usuario real del sistema, pero el cliente elegido

es el usuario efectivo del mismo.

Flujo basico:

1 El recepcionista quiere buscar a un cliente para trabajar con el.

2 El sistema pide al recepcionista que introduzca los parametros requeridos

para realizar la busqueda del cliente.

3 El recepcionista introduce todos, algunos o ninguno de los parametros reque-

ridos

4 El recepcionista confirma que desea buscar a un cliente que coincida con esos

parametros

5 El sistema muestra todos los clientes que coinciden con los parametros de

busqueda y pide al recepcionista que elija a uno de ellos.

Page 80: Xesthproyecto

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

Descripcion: Permite al recepcionista dejar de trabajar con la cuenta de un cliente.

Precondiciones: El recepcionista esta autenticado en el sistema y hay un cliente como usuario

efectivo.

Postcondiciones: El cliente deja de ser el usuario efectivo de la aplicacion.

Flujo basico:

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 peticion y el cliente deja de ser el usuario efectivo de

la aplicacion.

Flujo alternativo:

*.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el

proceso.

Page 81: Xesthproyecto

5.3. Casos de Uso 49

15. Dar de Alta Cliente

Actores Primarios: Recepcionista

Descripcion: Permite al recepcionista dar de alta a un nuevo cliente en el sistema cuando

llega al hotel para realizar una reserva.

Precondiciones: El recepcionista esta autenticado en el sistema.

Postcondiciones: El nuevo cliente pasa a estar registrado en el sistema y es usuario efectivo del

mismo.

Flujo basico:

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)

• Direccion completa (obligatorio)

• Paıs (obligatorio)

• Direccion de e-mail (obligatorio)

• Telefono1 (opcional)

• Telefono2 (opcional)

3 El recepcionista introduce los datos solicitados.

4 El recepcionista confirma que desea dar de alta al nuevo cliente.

5 El sistema procesa la informacion del nuevo cliente.

6 El nuevo cliente pasa a estar dada de alta como cliente y es usuario efectivo

del sistema en ese momento.

Page 82: Xesthproyecto

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 basico.

4.2.1 El DNI indica que esa persona ya esta dada de alta.

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

Descripcion: Permite al recepcionista modificar los datos con los que se dio de alta un cliente

del sistema.

Precondiciones: El recepcionista esta autenticado en el sistema y hay un cliente como usuario

efectivo.

Postcondiciones: Los datos del cliente estan actualizados.

Flujo basico:

1 El recepcionista quiere modificar los datos con los que se dio de alta el cliente

que esta como usuario efectivo en el sistema.

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)

Page 83: Xesthproyecto

5.3. Casos de Uso 51

• Fecha de Nacimiento (obligatorio)

• Direccion completa (obligatorio)

• Paıs (obligatorio)

• Direccion de e-mail (obligatorio)

• Telefono1 (opcional)

• Telefono2 (opcional)

3 El recepcionista modifica los datos que quiere.

4 El recepcionista confirma que desea actualizar los datos del cliente.

5 El sistema procesa la actualizacion de los datos del cliente.

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 basico.

17. Consultar datos de Cliente

Actores Primarios: Recepcionista

Descripcion: Permite al recepcionista consultar los datos con los que se dio de alta un cliente

en el sistema.

Precondiciones: El recepcionista esta autenticado en el sistema y hay un cliente como usuario

efectivo.

Postcondiciones: Ninguna.

Page 84: Xesthproyecto

5.3. Casos de Uso 52

Flujo basico:

1 El recepcionista quiere consultar los datos con los que se dio de alta el cliente

que esta como usuario efectivo en el sistema.

2 El sistema muestra al recepcionista los datos personales del cliente.

18. Dar de baja Cliente

Actores Primarios: Cliente

Descripcion: Permite al recepcionista dar de baja a un cliente como usuario del sistema.

Precondiciones: El recepcionista esta autenticado en el sistema y hay un cliente como usuario

efectivo.

Postcondiciones: El cliente deja de ser usuario efectivo del sistema y deja de existir como usuario

de la aplicacion.

Flujo basico:

1 El recepcionista quiere dar de baja del sistema al cliente que esta como

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 aplicacion.

Flujo alternativo:

*.1 En cualquier momento el recepcionista tiene la posibilidad de cancelar el

proceso.

Page 85: Xesthproyecto

5.3. Casos de Uso 53

5.3.4. Casos de Uso de Gestion de Reservas

Los Casos de Uso que aquı se detallan son todos los relacionados con la gestion de

las reservas en el establecimiento del hotel por parte del recepcionista a peticion de

un cliente. Se puede ver el diagrama correspondiente en la figura 5.4 de la pagina

81.

19. Hacer reserva

Actores Primarios: Recepcionista

Descripcion: Permite al recepcionista realizar una reserva de una o varias habitaciones para

un dıa determinado para el cliente que lo solicite

Precondiciones: El recepcionista esta autenticado en el sistema y el cliente esta como usuario

efectivo.

Postcondiciones: La reserva queda realizada a espera de que el cliente la pague.

Flujo basico:

1 El recepcionista quiere realizar una reserva de habitacion para el cliente que

es el usuario efectivo actual de la aplicacion.

2 La aplicacion pide al recepcionista que indique el tipo de habitacion que

desea reservar, el dıa que llega el cliente, el dıa de salida, y la cantidad de

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 habitacion para los dıas indicados.

5 El sistema procesa la reserva.

Page 86: Xesthproyecto

5.3. Casos de Uso 54

6 La reserva pasa a estar realizada a la espera de ser pagada y se le mues-

tra al recepcionista el numero de reserva para que la pueda localizar y

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 basico.

4.2.1 El recepcionista ha introducido una fecha de llegada o de salida erronea.

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 ha-

bitacion.

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

Descripcion: Permite al recepcionista consultar las reservas que ha realizado un cliente del

hotel, se podran ver las reservas pagadas, las canceladas y las que estan aun

pendientes de pago.

Precondiciones: El recepcionista esta autenticado en el sistema y el cliente esta como usuario

efectivo.

Page 87: Xesthproyecto

5.3. Casos de Uso 55

Postcondiciones: Ninguna.

Flujo basico:

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

Descripcion: Permite al recepcionista modificar una reserva realizada por un cliente.

Precondiciones: El recepcionista esta autenticado en el sistema, el cliente esta como usuario

efectivo, y la reserva no esta pagada ni cancelada.

Postcondiciones: La reserva queda modificada a espera de que el cliente la pague.

Flujo basico:

1 El recepcionista quiere modificar una reserva de habitaciones por peticion

del cliente.

2 El recepcionista indica que desea anadir una nueva reserva de habitacion.

3 La aplicacion pide al recepcionista que indique el tipo de habitacion que

desea reservar, el dıa que llega el cliente, el dıa de salida, y la cantidad de

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 habitacion para los dıas indicados.

6 El sistema procesa la reserva.

Page 88: Xesthproyecto

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 habitacion.

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 eliminacion de la lınea de reserva.

2.5 Se pasa al paso 2 del flujo basico.

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 basico.

5.2.1 El recepcionista ha introducido una fecha de llegada o de salida erronea.

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

Page 89: Xesthproyecto

5.3. Casos de Uso 57

Actores Primarios: Recepcionista

Descripcion: Permite al recepcionista consultar la factura de cualquier reserva que haya

realizado un cliente del hotel, se podran ver las facturas pagadas, las canceladas

y las que estan aun pendientes de pago.

Precondiciones: El recepcionista esta autenticado en el sistema y el cliente esta como usuario

efectivo.

Postcondiciones: Ninguna.

Flujo basico:

1 El recepcionista quiere consultar una factura de una reserva que ha realizado

el cliente.

2 El sistema pide al recepcionista que indique el numero de reserva para la

factura que desea consultar.

3 El recepcionista indica el numero de reserva deseado.

4 El sistema muestra al recepcionista la factura de la reserva solitada. En el

caso de que la factura ya este pagada o cancelada muestra el importe que

ha pagado y si la factura esta pendiente de pago muestra el total que debe

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

Page 90: Xesthproyecto

5.3. Casos de Uso 58

Descripcion: Permite al recepcionista cancelar cualquier reserva que haya realizado un cliente

y aun no disfrutado, si la factura estuviese pagada se le devuelve al cliente un

porcentaje del importe, dependiendo de la antelacion con la que la cancele.

Precondiciones: El recepcionista esta autenticado en el sistema y el cliente esta como usuario

efectivo.

Postcondiciones: La reserva queda cancelada.

Flujo basico:

1 El recepcionista quiere cancelar una reserva que ha realizado el cliente.

2 El sistema pide al recepcionista que indique el numero de reserva que desea

cancelar.

3 El recepcionista indica el numero de reserva deseado.

4 El sistema pide al recepcionista la confirmacion de que el cliente quiere can-

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 numero de reserva que ya habıa sido cancelada

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

Page 91: Xesthproyecto

5.3. Casos de Uso 59

Actores Primarios: Recepcionista

Actores de Soporte: Entidad Financiera

Descripcion: Permite al recepcionista marcar la factura de una reserva como pagada cuando

le paga el cliente.

Precondiciones: El recepcionista esta autenticado en el sistema y el cliente es el usuario efectivo.

Postcondiciones: La factura de la reserva esta pendiente de pago y no esta cancelada.

Flujo basico:

1 El recepcionista quiere pagar la factura de una reserva que ha realizado un

cliente.

2 El sistema pide al recepcionista que indique el numero de reserva que desea

pagar.

3 El recepcionista indica el numero de reserva deseado.

4 El sistema muestra al recepcionista la factura de la reserva y le pide la con-

firmacion de que quiere pagarla.

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 confirmacion y marca la factura como pagada.

Flujo alternativo:

(1-5).1 En cualquier momento el recepcionista tiene la posibilidad de cancelar

el proceso.

3.1 El recepcionista indica un numero de reserva que ya habıa sido pagado o

que ya esta en proceso de pago.

3.2 Se le muestra un error al recepcionista y se termina el proceso sin que se

pague la factura de la reserva.

Page 92: Xesthproyecto

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 Gestion de Habitaciones

Los Casos de Uso que aquı se detallan son todos los relacionados con la gestion de las

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 pagina 82.

25. Crear Tipo de Habitacion

Actores Primarios: Administrador

Descripcion: Permite al administrador crear un nuevo tipo de habitacion en el momento

que estime necesario, ya sea por apertura del hotel, reforma, modificacion de

habitaciones, etc. Los tipos de habitaciones son los que definen entre otras cosas

el precio base de una habitacion.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: El nuevo tipo de habitacion esta creado.

Flujo basico:

1 El administrador quiere crear un nuevo tipo de habitacion.

2 La aplicacion pide al administrador que introduzca los siguentes datos: Des-

cripcion del tipo de habitacion (obligatorio), Numero de personas para

las que esta acondicionada la habitacion (obligatorio) y precio base que

tendra una habitacion de este tipo (obligatorio).

3 El administrador especifica todos los datos solicitados.

4 El administrador confirma que desea crear un tipo de habitacion con los datos

indicados.

Page 93: Xesthproyecto

5.3. Casos de Uso 61

5 El sistema crea el nuevo tipo de habitacion.

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 basico.

26. Consultar Tipo de Habitacion

Actores Primarios: Recepcionista, Administrador

Descripcion: Permite al administrador consultar los datos de un tipo de habitacion.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

1 El administrador quiere consultar los datos de un tipo de habitacion.

2 El sistema pide al administrador que indique el tipo de habitacion que desea

consultar.

3 El administrador especifica el tipo que quiere consultar.

4 El sistema muestra al administrador el tipo de habitacion requerido.

Flujo alternativo:

*.1 En cualquier momento el administrador tiene la posibilidad de cancelar el

proceso.

Page 94: Xesthproyecto

5.3. Casos de Uso 62

3.1 El administrador no introduce un tipo de habitacion existente.

3.2 El sistema indica que no existe el tipo de habitacion especificado y se vuelve

al evento 2 del flujo basico.

27. Modificar Tipo de Habitacion

Actores Primarios: Administrador

Descripcion: Permite al administrador modificar un tipo de habitacion en el momento que

estime necesario, ya sea por reforma, modificacion de habitaciones, etc.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: El tipo de habitacion esta actualizado.

Flujo basico:

1 El administrador quiere modificar un tipo de habitacion.

2 El sistema pide al administrador que indique el tipo de habitacion que desea

modificar.

3 El administrador especifica el tipo que quiere actualizar.

4 La aplicacion muestra al administrador los datos del tipo de habitacion y

pide a este que actualice los siguentes datos: Descripcion del tipo de habi-

tacion (obligatorio), Numero de personas para las que esta acondicionada

la habitacion (obligatorio) y precio base que tendra una habitacion de este

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 habitacion con los nuevos datos.

Flujo alternativo:

Page 95: Xesthproyecto

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 habitacion existente.

3.2 El sistema indica que no existe el tipo de habitacion especificado y se vuelve

al evento 2 del flujo basico.

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 basico.

28. Crear Habitacion

Actores Primarios: Administrador

Descripcion: Permite al administrador crear una nueva habitacion en el momento que estime

necesario, ya sea por apertura del hotel, reforma, modificacion de habitaciones,

etc. Los tipos de habitaciones son los que definen entre otras cosas el precio

extra de una habitacion, y el tipo de habitacion.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: La nueva habitacion esta creada.

Flujo basico:

1 El administrador quiere crear una nueva habitacion.

2 La aplicacion pide al administrador que introduzca los siguentes datos: Ti-

po de habitacion (obligatorio), Numero de habitacion (obligatorio), piso

en el que esta la habitacion y precio extra que tendra esta habitacion en

particular.

3 El administrador especifica todos los datos solicitados.

Page 96: Xesthproyecto

5.3. Casos de Uso 64

4 El administrador confirma que desea crear una habitacion con los datos in-

dicados.

5 El sistema crea la nueva habitacion.

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 basico.

29. Consultar Habitacion

Actores Primarios: Recepcionista, Administrador

Descripcion: Permite al administrador consultar los datos de una habitacion.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

1 El administrador quiere consultar los datos de una habitacion.

2 El sistema pide al administrador que indique el numero de la habitacion que

desea consultar.

3 El administrador especifica el numero de habitacion que quiere consultar.

4 El sistema muestra al administrador los datos de la habitacion requerida.

Flujo alternativo:

Page 97: Xesthproyecto

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 numero de habitacion existente.

3.2 El sistema indica que no existe la habitacion especificada y se vuelve al

evento 2 del flujo basico.

30. Modificar Habitacion

Actores Primarios: Administrador

Descripcion: Permite al administrador modificar una habitacion en el momento que estime

necesario, ya sea por reforma, etc.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: La habitacion esta actualizada.

Flujo basico:

1 El administrador quiere modificar los datos de una habitacion.

2 El sistema pide al administrador que indique el numero de la habitacion que

desea modificar.

3 El administrador especifica el numero de la habitacion que quiere actualizar.

4 La aplicacion muestra al administrador los datos de la habitacion y pide

a este que actualice los siguentes datos: Tipo de habitacion (obligatorio),

Numero de la habitacion (obligatorio), piso (obligatorio) y precio extra que

tendra esta habitacion en particular.

5 El administrador especifica todos los datos solicitados.

6 El administrador confirma que desea guardar los cambios realizados.

7 El sistema actualiza la habitacion con los nuevos datos.

Page 98: Xesthproyecto

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 numero de habitacion existente.

3.2 El sistema indica que no existe la habitacion especificada y se vuelve al

evento 2 del flujo basico.

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 basico.

31. Registrar Incidencia de Habitacion

Actores Primarios: Administrador

Descripcion: Permite al administrador registrar alguna incidencia que haya tenido lugar en

una de las habitaciones del hotel.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: La incidencia queda registrada y asociada a la habitacion pertinente.

Flujo basico:

1 El administrador quiere registrar una nueva incidencia.

2 El sistema pide al administrador que indique el numero de la habitacion a la

cual desea asociar la incidencia.

3 El administrador especifica el numero de la habitacion que requerido.

4 La aplicacion pide al administrador que introduzca los siguentes datos: Tipo

de incidencia (obligatorio): grave, leve, etc, y una descripcion textual de lo

ocurrido.

5 El administrador especifica todos los datos solicitados.

Page 99: Xesthproyecto

5.3. Casos de Uso 67

6 El administrador confirma que desea registrar la incidencia.

7 El sistema registra la incidencia asociada a la habitacion que procede.

Flujo alternativo:

*.1 En cualquier momento el administrador tiene la posibilidad de cancelar el

proceso.

3.1 El administrador no introduce un numero de habitacion existente.

3.2 El sistema indica que no existe la habitacion especificada y se vuelve al

evento 2 del flujo basico.

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 basico.

32. Consultar Incidencias de Habitacion

Actores Primarios: Administrador

Descripcion: Permite al administrador consultar todas las incidencias que hayan tenido lugar

en una de las habitaciones del hotel.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

1 El administrador quiere consultar las incidencias de una habitacion.

2 El sistema pide al administrador que indique el numero de la habitacion de

la cual desea consultar las incidencias.

3 El administrador especifica el numero de la habitacion que requerido.

Page 100: Xesthproyecto

5.3. Casos de Uso 68

4 El sistema muestra al administrador todas las incidencias ocurridas en esa

habitacion.

Flujo alternativo:

*.1 En cualquier momento el administrador tiene la posibilidad de cancelar el

proceso.

3.1 El administrador no introduce un numero de habitacion existente.

3.2 El sistema indica que no existe la habitacion especificada y se vuelve al

evento 2 del flujo basico.

5.3.6. Casos de Uso de Gestion de Ofertas

Los Casos de Uso que aquı se detallan son todos los relacionados con la gestion de

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 que ofertas son incompatibles con que otras, y las reglas

de aplicacion por las que se regiran, estas reglas definiran el contexto en el cual una

oferta se podra aplicar. Se puede ver el diagrama correspondiente en la figura 5.6 de

la pagina 83.

33. Crear Tipo de Oferta

Actores Primarios: Administrador

Descripcion: Permite al administrador crear un nuevo tipo de oferta en el momento que

estime necesario. Los tipos de oferta son los que definen entre otras cosas a

que se podra aplicar la oferta, reservas de habitaciones, servicios extra, etc, y

con que otros tipos de oferta sera incompatible.

Precondiciones: El administrador esta autenticado en el sistema.

Page 101: Xesthproyecto

5.3. Casos de Uso 69

Postcondiciones: El nuevo tipo de oferta esta creado.

Flujo basico:

1 El administrador quiere crear un nuevo tipo de oferta.

2 La aplicacion pide al administrador que introduzca los siguentes datos: Nom-

bre para el tipo de oferta (obligatorio), Descripcion del tipo de oferta (obli-

gatorio), A que se podra aplicar este tipo de oferta (obligatorio) y cantidad

mınima (obligatorio), y con que otros tipos de oferta sera incompatible este

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 basico.

34. Consultar Tipo de Oferta

Actores Primarios: Administrador

Descripcion: Permite al administrador consultar los datos de un tipo de oferta.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: Ninguna.

Page 102: Xesthproyecto

5.3. Casos de Uso 70

Flujo basico:

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 basico.

35. Modificar Tipo de Oferta

Actores Primarios: Administrador

Descripcion: Permite al administrador modificar un tipo de oferta en el momento que estime

necesario.

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: El tipo de oferta esta actualizado.

Flujo basico:

1 El administrador quiere modificar un tipo de oferta.

2 El sistema pide al administrador que indique el tipo de habitacion que desea

modificar.

Page 103: Xesthproyecto

5.3. Casos de Uso 71

3 El administrador especifica el tipo que quiere actualizar.

4 La aplicacion muestra al administrador los datos del tipo de oferta y pide a

este que actualice los siguentes datos: Nombre para el tipo de oferta (obliga-

torio), Descripcion del tipo de oferta (obligatorio), A que se podra aplicar

este tipo de oferta (obligatorio) y cantidad mınima (obligatorio), y con

que otros tipos de oferta sera incompatible este 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 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 basico.

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 basico.

36. Crear Oferta

Actores Primarios: Administrador

Descripcion: Permite al administrador crear una nueva oferta en el momento que estime

necesario, ya sea por apertura del hotel, eventos especiales, etc. Las Ofertas son

las que definen entre otras cosas a quien se le podra aplicar una oferta gracias

a las reglas que se pueden definir, fechas de aplicacion, etc.

Page 104: Xesthproyecto

5.3. Casos de Uso 72

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: La nueva oferta esta creada pero como un borrador que luego habra que revisar

y publicar.

Flujo basico:

1 El administrador quiere crear una nueva oferta.

2 La aplicacion pide al administrador que introduzca los siguentes datos: Ti-

po de oferta (obligatorio), Fecha en la que se comenzara y terminara la

aplicacion de la oferta (obligatorio), Descuento que ofrece esta oferta (obi-

gatorio), Descripcion de la oferta (obligatorio) y regla que sera utilizada

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 basico.

37. Consultar Oferta

Actores Primarios: Administrador

Descripcion: Permite al administrador consultar los datos de una oferta.

Page 105: Xesthproyecto

5.3. Casos de Uso 73

Precondiciones: El administrador esta autenticado en el sistema.

Postcondiciones: Ninguna.

Flujo basico:

1 El administrador quiere consultar los datos de una oferta.

2 El sistema pide al administrador que indique el numero de la oferta que desea

consultar.

3 El administrador especifica el numero de oferta que quiere consultar.

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 numero de oferta existente.

3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento

2 del flujo basico.

38. Modificar Oferta

Actores Primarios: Administrador

Descripcion: Permite al administrador modificar una oferta en el momento que estime nece-

sario, ya sea por reforma, etc, siempre y cuando esta oferta aun sea un borrador.

Precondiciones: El administrador esta autenticado en el sistema y la oferta aun esta marcada

como borrador y no ha sido publicada.

Postcondiciones: La oferta esta actualizada.

Page 106: Xesthproyecto

5.3. Casos de Uso 74

Flujo basico:

1 El administrador quiere modificar los datos de una oferta.

2 El sistema pide al administrador que indique el numero de la oferta que desea

modificar.

3 El administrador especifica el numero de la oferta que quiere actualizar.

4 La aplicacion muestra al administrador los datos de la oferta y pide a este que

actualice los siguentes datos: Tipo de oferta (obligatorio), Fecha en la que

se comenzara y terminara la aplicacion de la oferta (obligatorio), Descuento

que ofrece esta oferta (obigatorio), Descripcion de la oferta (obligatorio) y

regla que sera utilizada por el sistema a la hora de saber si una oferta se

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 numero de oferta existente.

3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento

2 del flujo basico.

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 basico.

39. Eliminar Oferta

Page 107: Xesthproyecto

5.3. Casos de Uso 75

Actores Primarios: Administrador

Descripcion: Permite al administrador eliminar una oferta que estaba como borrador.

Precondiciones: El administrador esta autenticado en el sistema, la oferta no esta publicada y

esta marcada como borrador.

Postcondiciones: La oferta esta eliminada y deja de existir.

Flujo basico:

1 El administrador quiere eliminar una oferta.

2 El sistema pide al administrador que indique el numero de la oferta que desea

eliminar.

3 El administrador especifica el numero de oferta requerido.

4 La aplicacion pide al administrador la confirmacion de que desea eliminar la

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 numero de oferta existente.

3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento

2 del flujo basico.

40. Publicar Oferta

Actores Primarios: Administrador

Page 108: Xesthproyecto

5.3. Casos de Uso 76

Descripcion: Permite al administrador publicar una oferta para que la puedan disfrutar los

clientes.

Precondiciones: El administrador esta autenticado en el sistema y la oferta no esta publicada.

Postcondiciones: La oferta queda publicada.

Flujo basico:

1 El administrador quiere publicar una oferta.

2 El sistema pide al administrador que indique el numero de la oferta que desea

publicar.

3 El administrador especifica el numero la oferta requerido.

4 La aplicacion pide al administrador la confirmacion de que desea publicar la

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 numero de oferta existente.

3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento

2 del flujo basico.

41. Dar de baja Oferta

Actores Primarios: Administrador

Page 109: Xesthproyecto

5.3. Casos de Uso 77

Descripcion: Permite al administrador dar de baja una oferta. Esto es un mecanismo de

seguridad por si se publico una oferta por error o descuido que pueda afectar

gravemente a la economıa del establecimiento.

Precondiciones: El administrador esta autenticado en el sistema y la oferta esta publicada.

Postcondiciones: La oferta deja de estar publicada.

Flujo basico:

1 El administrador quiere dar de baja una oferta.

2 El sistema pide al administrador que indique el numero de la oferta que desea

dar de baja.

3 El administrador especifica el numero de oferta requerido.

4 El sistema pide al administrador la confirmacion de que desea dar de baja la

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 publico.

Flujo alternativo:

*.1 En cualquier momento el administrador tiene la posibilidad de cancelar el

proceso.

3.1 El administrador no introduce un numero de oferta existente.

3.2 El sistema indica que no existe la oferta especificada y se vuelve al evento

2 del flujo basico.

Page 110: Xesthproyecto

5.4. Modelo de Casos de Uso 78

5.4. Modelo de Casos de Uso

5.4.1. Gestion de Usuarios Web

Figura 5.1: Diagrama de Casos de Uso de Gestion de Usuarios Web

Page 111: Xesthproyecto

5.4. Modelo de Casos de Uso 79

5.4.2. Gestion de Reservas Web

Figura 5.2: Diagrama de Casos de Uso de Gestion de Reservas Web

Page 112: Xesthproyecto

5.4. Modelo de Casos de Uso 80

5.4.3. Gestion de Clientes

Figura 5.3: Diagrama de Casos de Uso de Gestion de Clientes

Page 113: Xesthproyecto

5.4. Modelo de Casos de Uso 81

5.4.4. Gestion de Reservas

Figura 5.4: Diagrama de Casos de Uso de Gestion de Reservas

Page 114: Xesthproyecto

5.4. Modelo de Casos de Uso 82

5.4.5. Gestion de Habitaciones

Figura 5.5: Diagrama de Casos de Uso de Gestion de Habitaciones

Page 115: Xesthproyecto

5.4. Modelo de Casos de Uso 83

5.4.6. Gestion de Ofertas

Figura 5.6: Diagrama de Casos de Uso de Gestion de Ofertas

Page 116: Xesthproyecto
Page 117: Xesthproyecto

Capıtulo 6

Diseno de la aplicacion

6.1. Arquitectura General

Para el desarrollo de este proyecto se va a seguir el patron arquitectonico Modelo-Vista-

Controlador cuyo objetivo es desligar el diseno de las interfaces de usuario del resto del

sistema. Hoy en dıa es la tecnica habitual de diseno de interfaces en la programacion

Web con J2EE. Con esta tecnica se consiguen principalmente dos cosas: que el modelo

sea reusable con distintas vistas, lo que es una ventaja si el dıa de manana se quiere

realizar una interfaz grafica local; y gracias a que se desarrolla de esta forma el software,

se puede dividir el trabajo de forma clara dentro de un equipo, segun la especialidad de

cada miembro.

Pero la arquitectura mejora cuando se usan conjuntamente con el patron arquitectonico

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 abstraccion que representa a los objetos de la aplicacion que se

esta desarrollando, en esta capa se incluyen tanto los datos (Bases de Datos, Ficheros,

85

Page 118: Xesthproyecto

6.1. Arquitectura General 86

etc) como las reglas de negocio (el comportamiento que debe tener la aplicacion). No tiene

conocimiento de ninguna de las otra dos partes, vista y controlador.

La Vista El la capa encargada de la representacion visual de los datos del modelo, para

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

efectua sobre la vista, para a continuacion invocar las acciones pertinentes del modelo,

normalmente, y ası es en este caso, es el unico que conoce a las otras dos capas, modelo y

vista.

A continuacion (figura 6.1) se muestra un pequeno esquema de como se va a dividir el

sistema que se esta desarrollando con algunos de los subsitemas que se pueden encontrar

en cada una de las capas.

Figura 6.1: Arquitectura General Del Sistema (Modelo-Vista-Controlador)

Page 119: Xesthproyecto

6.2. Capa de la Vista 87

En las siguientes secciones se explica cada una de estas tres capas en detalle, que contiene,

que objetivos se persiguen, patrones y tecnologıas utilizados.

6.2. Capa de la Vista

La capa vista incluye todos aquellos paquetes y artefactos necesarios para la presentacion

grafica. En esta capa se incluyen las paginas JSP y los objetos que estas necesitan para

una correcta representacion de los datos.

En esta capa se usa la tecnologıa JSP que permite escribir paginas web usando codigo

java, pero, para no incluir codigo java en las paginas web de este proyecto, se usara el API

de JSTL que permite ocultar todo el codigo java mediante etiquetas ya predefinidas. De

esta forma se consigue que en un futuro un disenador grafico pueda disenar la forma que

deben tener las paginas sin tener que saber nada sobre el lenguaje de programacion Java.

Como se puede observar en la figura 6.2, esta capa se divide en dos partes bien diferen-

ciadas, una de ellas es la que contiene las paginas JSP y la otra es donde estan ubicados

los recursos java que estas paginas necesitan para poder mostrar su contenido.

Figura 6.2: Arquitectura de la Capa Vista

Page 120: Xesthproyecto

6.2. Capa de la Vista 88

6.2.1. 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 paginas JSP que se explicaran a continuacion solo tienen que

definir la estructura general y el contenido, dejando toda la parte de presentacion para la

hoja de estilos.

Los estilos se han definido todos tomando como base un estilo css libre y se ha adaptado

totalmente para que la relacion de tamanos se hiciese de forma relativa y no absoluta, esto

se consigue adaptando todos los tamanos y posiciones, expresandolos de forma porcentual.

Con esto se consigue que, sea cual sea la resolucion del ordenador desde el que se visualice

la aplicacion, esta no tenga unas dimensiones fijas, sino que se adapte a las dimensiones

del navegador.

6.2.2. Paginas JSP

Para la presentacion mediante paginas JSP se usa un sistema de plantillas, ası simple-

mente hay que definir la apariencia global de un grupo de paginas y todas aquellas que

extiendan esa plantilla tendran una apariencia similar. En el caso de este proyecto, se

considero que al haber tres tipos de usuarios bien diferenciados, serıa una buena idea que

hubiese tres plantillas distintas para diferenciar claramente que tipo de usuario esta en la

aplicacion en cada momento.

A su vez dentro de cada plantilla hay dos opciones de presentacion, que se diferencian

usando luego hojas de estilo en cascada (CSS). Por un lado estan las paginas que solo

muestran informacion, y aquellas que ademas de mostra informacion tienen una barra

lateral que permite escoger la operacion que se desea realizar. En el caso que nos ocupa

se usa el sistema de plantillas Tiles de Struts.

Ademas Struts nos proporciona un sistema mediante el cual mostrar y recoger datos de

formularios se realiza de forma mas sencilla. Este sistema lo proporcionan los servlet y los

Page 121: Xesthproyecto

6.2. Capa de la Vista 89

ActionForms que define el programador y cuyo funcionamiento se detalla en una seccion

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 aplicacion

web en un fichero XML. Despues de tener las pantallas definidas, se pueden usar tags

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 pagina JSP que contiene la estructura basica de este conjunto

de ventanas y todo aquello que es comun a todas ellas.

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 basica de cada grupo de pantallas se define en una pagina JSP que se

llama DefaultLayout.jspx y las partes comunes se especificaran en DefaultFooter.jspx y

DefaultTitle.jspx.

Figura 6.3: Plantilla de una ventana

Page 122: Xesthproyecto

6.2. Capa de la Vista 90

Tıtulo Es la zona donde ira el nombre de la empresa y el tıtulo de la parte de la aplicacion

en la que se esta trabajando.

Cabezera Aquı se mostrara una pequena descripcion de la operacion en curso que se

muestra en la parte de Contenido.

Contenido Aquı se mostrara el resultado de la operacion solicitada por el usuario:

tablas, formularios, imagenes, etc.

Menu En esta zona se posicionaran los enlaces a las distintas operaciones que el usuario

puede realizar.

Pie de pagina Este es el lugar donde se pondra el nombre del desarrollador, licencia

bajo la que esta publicado el software, polıtica de privacidad, etc.

Una vez terminada la aplicacion, el resultado no tiene nada que ver con rectangulos

como se observo en la figura anterior, sino que quedarıa algo como lo que se muestra en

la siguiente imagen.

Figura 6.4: Resultado Final de una ventana

Page 123: Xesthproyecto

6.2. Capa de la Vista 91

6.2.3. ActionForms

Un ActionForm es simplemente un Bean que contiene las funcionalidades basicas de un

formulario, entrada y recuperacion de los datos de cada campo, y ademas proporciona, si

es necesario, una validacion de los datos a la hora del procesamiento de los mismos.

Definir un ActionForm es muy sencillo, simplemente hay que heredar de la clase Action-

Form que proporciona Struts y luego el Objeto que se esta construyendo debe contener

metodos Get y Set para todos los campos del formulario. Luego para trabajar con este

Objeto hay que especificar en el fichero de configuracion de Struts donde se encuentra el

objeto y a la hora de usarlo en una accion simplemente se tiene que indicar que se va a

utilizar dicho objeto y si se desea que se valide el contenido antes de pasarselo a la accion.

En la pagina JSP cuando dentro de una etiqueta ’<form>’ se desea especificar que un

campo determinado, va a ser un campo del objeto ActionForm que se ha definido para ese

formulario, simplemente se le anade a la etiqueta correspondiente el atributo ’property’

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 accion que lo gestiona,

el ActionForm que corresponda, de forma que en la accion de Struts se puede recuperar

de forma sencilla el valor del formulario, o viceversa, introducir datos previamente en un

formulario antes de que sea mostrado.

6.2.4. Internacionalizacion

Internacionalizar una aplicacion consiste en que esta sea accesible y funcione correcta-

mente sea cual sea el paıs e idioma donde se utiliza el sistema. Localizar una aplicacion no

es simplemente que los textos aparezcan en otro idioma, sino que tambien hay que tener

en cuenta otros detalles como por ejemplo la representacion de numeros, porcentajes o

fechas. Ya que en paıses como Gran Bretana los decimales se representan con un punto

como separador mientras que en Espana se indica con una coma.

Page 124: Xesthproyecto

6.2. Capa de la Vista 92

En un sistema como el que se esta desarrollando es obligatoria la intenacionalizacion.

En otras aplicaciones es aconsejable, pero en esta no puede faltar ya que al tratarse de

una aplicacion para un hotel, que esta estea internacionalizada permite que el sistema sea

accesible para gente de muchos paıses.

La internacionalizacion de aplicaciones web empresariales con paginas JSP es muy sen-

cilla utilizando las etiquetas que nos proporciona la librerıa JSTL. Lo mas complicado es

integrar la localizacion de JSTL con la que proporciona Struts ya que, entre otras cosas,

utilizan procesos distintos para localizar las traducciones. La librerıa de JSTL proporciona

las etiquetas ’<fmt:xxxxxx/>’ que sirven proporcionan formas sencillas para especificar

mensajes, ya que solo hay que indicar la clave correspondiente del fichero de mensajes,

ademas estas etiquetas proporcionan metodos simples para internacionalizar numeros de-

cimales, porcentajes o las distintas fechas.

Lo primero que hay que hacer es especificar en los distintos ficheros de configuracion

como se llaman los archivos que contienen las traducciones. Las traducciones dentro de

estos ficheros tienen la forma clave=valor. En este caso los ficheros tendran como nom-

bre Messages.properties la traduccion basica por defecto que estara en ingles y Messa-

ges ll CC.properties las demas traducciones donde ’ll’ es el codigo de idioma y ’CC’ el

codigo de paıs que identifican unıvocamente la traduccion. Los codigos de los idiomas

estan definidos en el estandar ISO 639 y los codigos de los paıses en el estandar ISO 3166.

Cuando se inicia la aplicacion esta coge como idioma el mismo que tiene el navegador

del cliente, si no se puede identificar entonces se tomara el idioma del servidor web, y si

tampoco se puede identificar o el idioma aun no esta soportado, entonces se escogera el

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 esta realizando, esta internacionalizacion se realizara en tres idio-

mas: Gallego, Castellano e Ingles. Con estos tres idiomas se puede acceder a muchısimos

Page 125: Xesthproyecto

6.3. Capa del Controlador 93

millones de personas. Aunque sera muy sencillo realizar nuevas traducciones para otros

idiomas, simplemente se crea un nuevo fichero con los codigos de idioma y paıs desea-

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 repre-

sentacion de algunos datos, en el caso de este proyecto se necesitaba por ejemplo de un

objeto que sirviera para mostrar las fechas, algo muy util ya que la utilizacion de fechas

es muy comun entre muchos de los casos de uso que se implementan. Esta clase se llama

DateRanges, se ha aprovechado de la implentacion de un ejemplo que distribuyeron en la

asignatura de IS de quinto curso de Ingenierıa Informatica.

Por otro lado tambien se vio la necesidad de una clase que sirviera de cache para mostrar

los tipos de habitacion que hay en el sistema. Como los tipos de habitacion se utilizan

mucho, serıa muy ineficiente consultarlos en la base de datos cada vez que se quisieran

mostrar. Por eso, esta clase guarda en memoria todos los tipos de habitacion tan pronto

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 separacion de la vista y del modelo. Para el diseno de esta capa se utilizan una serie de

patrones arquitectonicos que se muestran a continuacion en las siguientes secciones.

En esta capa es en la que se centra principalmente Struts, proporcionando todas las

implementaciones basicas que se necesitan para el desarrollo de una aplicacion web em-

presarial.

Page 126: Xesthproyecto

6.3. Capa del Controlador 94

6.3.1. Patron Front Controller

El patron Front Controller consiste en que, cada vez que el servidor recibe una nueva

peticion siempre la procesa el mismo controlador, que lo unico que hace es delegar en otras

clases para que resuelvan la peticion. Para esto struts proporciona la clase ActionServlet

que luego hay que extender para anadirle nuevas funcionalidades personalizadas como

filtros de procesado.

Lo primero que se hace es indicar en el fichero de configuracion del servidor, que todas

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 patron que siguen (en este caso *.do) y a continuacion especificar el

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 patron.

Page 127: Xesthproyecto

6.3. Capa del Controlador 95

javax.servlet.http.HttpServlet

org.apache.struts.action.ActionServlet

#doGet()#doPost()

org.apache.struts.action.Action

+execute()

1 0..*

org.apache.struts.action.ActionForm

+reset()+validate()

<<instantiate>>

<<call>>

Action1 ActionN

ActionForm1 ActionFormN

<<call>>

Figura 6.5: Patron Front Controller General

Ahora vamos a describir como se relacionan las clases que se ven en el diagrama anterior.

Cuando el servidor web recibe una peticion comprueba si la URL solicitada cumple

alguno de los patrones que se especifican en su fichero de configuracion web.xml, si es ası,

entonces crea una instancia del ActionServlet que tiene indicado para manejar esa peticion.

En el caso del proyecto que se esta desarrollando, el ActionServlet que gestionara las

peticiones de URLs terminadas en ’.do’ sera HotelPortalRequestProcessor. En este caso

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 peticion pase por el procesador de Tiles.

A continuacion el HotelPortalRequestProcessor tiene que llamar a la accion que se ha

especificado para gestionar la URL en concreto que le ha llegado. Ademas entre otras cosas

Page 128: Xesthproyecto

6.3. Capa del Controlador 96

a la accion que se va a invocar se le pasara, en caso de que hubiese alguno, el formulario

asociado a esa accion (ActionForm).

Si solo se quisiera la funcionalidad que se acaba de mencionar, no harıa falta crear un

procesador de acciones propio, valdrıa de igual forma el procesador de acciones de Tiles.

Pero como el sistema que se esta desarrollando es algo complejo, se necesita de algo mas.

En primer lugar se va a necesitar mantener las sesiones de los usuarios activas y cuando

un usuario haga una peticion, sera indispensable comprobar que este esta autenticado en

la aplicacion.

Ademas es tambien una buena idea que en este momento de la peticion, cuando aun

no se ha hecho nada importante, se comprobase si el usuario que esta autenticado en

la aplicacion tiene acceso a la accion que intenta llevar a cabo, y si no es ası no se le

permitira realizarla.

Implementar este tipo de controles no es tarea facil, por lo tanto se busca algun tipo de

patron que pueda ayudar a resolver esta cuestion. El patron que se usara sera el llamado

Chain of Responsability (Cadena de Responsabilidad) a traves de una cadena de filtros, por

los cuales pasara la peticion, si en el contexto en el que se esta se cumplen las condiciones

de todos los filtros entonces la peticion seguira adelante.

6.3.2. Patron Chain of Responsability

Este patron, Cadena de Responsabilidad, utiliza la delegacion como proceso basico para

realizar su cometido. En este caso se usa una cadena de filtros por la cual pasa la peticion

inicial. Esta cadena funciona de la siguiente forma.

La peticion entra en el primer filtro, este comprueba si se cumple alguna de las condi-

ciones preestablecidas para las que tiene una respuesta ya predefinida, es decir, que con

la informacion que tiene el filtro ya puede decir que accion se tiene que ejecutar luego. Si

ninguna de las condiciones del filtro se cumple, entonces este delega toda la responsabili-

Page 129: Xesthproyecto

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 aplicacion de este proyecto se usan cuatro filtros a traves de los cuales deben pasar

todas las peticiones. Estos filtros son los que se muestran a continuacion, por orden de

aplicacion.

SessionPreProcessingFilter Este filtro lo primero que hace es comprobar si la sesion

del usuario aun esta activa, en caso afirmativo no hace nada. Si la sesion ha terminado

tiene que comprobar si el usuario tiene su nombre y contrasena guardadas en las cookies,

y si es ası reestablecerle la sesion. A diferencia de otros filtros, este filtro no interrumpe la

ejecucion de la cadena, simplemente sirve para que en todas las peticiones se este comple-

temente seguro de que la sesion esta activa.

AuthenticationPreProcessingFilter Este es uno de los filtros mas importantes ya

que es el encargado de verificar si el usuario que esta utilizando la aplicacion esta au-

tenticado o no. En caso de que lo este no hace nada y ejecuta el siguiente filtro de la

cadena, pero si el usuario no esta autenticado, tiene que comprobar si la accion que quiere

realizar requiere de autenticacion, de ser ası este filtro enviarıa al usuario a la pagina de

autenticacion.

AdminOnlyPreProcessingFilter El filtro AdminOnly proporciona una comprobacion

de acceso, al estar despues del filtro que comprueba si el usuario esta autenticado, ya se

sabe que el usuario esta autenticado, por lo que este filtro tiene la mision de chequear si la

accion que se desea realizar es una accion que solo puede realizar el administrador, de ser

ası el filtro debe comprobar que el usuario que solicita la accion es el administrador, una

vez realizada esta comprobacion, si el usuario es el administrador entonces se le permite

realizar la operacion, y si no lo es se le envıa a la pagina principal.

Page 130: Xesthproyecto

6.3. Capa del Controlador 98

RecepcionistOnlyPreProcessingFilter Este filtro proporciona otra comprobacion de

acceso, al estar despues del filtro que comprueba si el usuario esta autenticado, ya se sabe

que el usuario esta autenticado, por lo que este filtro tiene la mision de chequear si la

accion que se desea realizar es una accion que solo puede realizar el recepcionista, de ser

ası el filtro debe comprobar que el usuario que solicita la accion es el recepcionista, una

vez realizada esta comprobacion, si el usuario es el recepcionista entonces se le permite

realizar la operacion, y si no lo es se le envıa a la pagina principal.

6.3.3. Acciones

Una vez que la peticion ha pasado los filtros y estos han decidido que accion realizar,

entonces el ActionServlet de Struts debe llamar a la accion a la cual corresponda realizar

la operacion solicitada. En el fichero de configuracion de struts, struts-config.xml, es donde

se encuentran definidas las URLs y la accion que se debe ejecutar cuando se solicita dicha

URL.

Ademas de la accion que se tiene que ejecutar, en este fichero tambien se pueden definir

propiedades, para que luego puedan ser utilizadas por ejemplo por los filtros, y redirec-

ciones con nombre, de forma que cuando una accion se ejecute pueda usar esos nombres

para redirigir la accion a una pagina u otra accion. Por otro lado, se indican, de la misma

forma, los ActionForm correspondientes a los formularios que debe manejar y procesar

cada accion.

En este caso, para una mejor comprension del sistema, las acciones se han dividido

en paquetes segun lo que manejan, o para que se utilizan dichas acciones, como se pue-

de observar en la figura 6.6. Por ejemplo, hay paquetes donde estan todas las acciones

relacionadas con las reservas u otro donde estan las que tienen relacion con las ofertas,

etc.

Page 131: Xesthproyecto

6.3. Capa del Controlador 99

Ademas para facilitar el manejo de diversas operaciones que pueden tomar mas de una

accion para realizarse, se vio la nececidad de crear unas clases de apoyo a las que se le dio

el nombre de XXXManager.

http.controller

actions

offers

reservations

rooms

session

frontcontroller

clients

misc

offers

payment

reservations

rooms

users

Figura 6.6: Paquetes - Distribucion de Acciones de Struts

A continuacion se muestra en la figura 6.7 el diagrama de como se organiza realmente

el patron Front Controller junto con el de Chain of Responsability en el desarrollo final

de este proyecto.

6.3.4. Clases de Utilidad y Soporte a Acciones

Para dar soporte a la estructura del patron Front Controller se definen clases abstractas

que tienen que ser luego extendidas por las acciones y los formularios, pero ademas de poder

agrupar las acciones todas bajo una misma clase padre, esta clase abstracta tambien sirve

para realizar operaciones comunes a todas las acciones, como el procesamiento de algunas

excepciones, etc.

Page 132: Xesthproyecto

6.3. Capa del Controlador 100

org::apache::struts::tiles::TilesRequestProcessor

org::apache::struts::action::Actionorg::apache::struts::action::ActionForm

http::util::struts::action::DefaultAction

+execute(... : ...) : ActionForward

#doExecute(... : ...)#doOnInternalErrorException(... : ...)

http::util::struts::action::DefaultActionForm

#getLocale(request : HttpServletRequest) : Locale

-serialVersionUID : long

http::controller::frontcontroller::HotelPortalRequestProcessor

<<create>> +HotelPortalRequestProcessor()#processActionPerform(... : ...) : ActionForward

~firstPreProcessingFilter : PreProcessingFilter

1

0..*

<<call>>

http::controller::frontcontroller::PreProcessingFilter

<<create>> +PreProcessingFilter(nextFilter : PreProcessingFilter)+process(... : ...) : ActionForward

#doProcess(... : ...) : ActionForward#doOnInternalErrorException(... : ...) : ActionForward

-nextFilter : PreProcessingFilter

<<create>>

http::controller::frontcontroller::SessionPreProcessingFilter

<<create>> +SessionPreProcessingFilter(... : ...)#doProcess(... : ...) : ActionForward

http::controller::frontcontroller::AuthenticationPreProcessingFilter

<<create>> +AuthenticationPreProcessingFilter(... : ...)#doProcess(... : ...) : ActionForward

http::controller::frontcontroller::AdminOnlyPreProcessingFilter

<<create>> +AdminOnlyPreProcessingFilter(... : ...)#doProcess(... : ...) : ActionForward

http::controller::frontcontroller::ReceptionistOnlyPreProcessingFilter

<<create>> +ReceptionistOnlyPreProcessingFilter(... : ...)#doProcess(... : ...) : ActionForward

http::view::actionforms::FindClientsForm

http::view::actionforms::FindIncidentsForm

http::view::actionforms::FindOffersForm

http::view::actionforms::FindReservationsForm

http::view::actionforms::FindRoomsForm

http::view::actionforms::IncidentForm

http::view::actionforms::LoginForm http::view::actionforms::OfferForm

http::view::actionforms::OfferTypeFormhttp::view::actionforms::RoomForm

http::view::actionforms::RoomReservationForm

http::view::actionforms::RoomTypeForm

http::view::actionforms::UserProfileForm

Todas las acciones que extienden esta clase se encuentran en los paqueteshttp.controller.actions.clients, misc, offers,payment, reservations, rooms y users.

Pero no se incluyen aquí porque son una gran cantidad, además todas estas acciones hacen uso de los actionFormsque se incluyeron en este diagrama

Figura 6.7: Diagrama Aplicacion de Front Controller

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 metodos que proporcionan las

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 man-

tener alguna informacion en cache a la espera de algunos otros datos para luego poder

enviar todo junto al metodo correspondiente de la fachada del modelo. Estas clases de

soporte son las siguientes:

Page 133: Xesthproyecto

6.3. Capa del Controlador 101

SessionManager Esta clase proporciona diferentes metodos que ayudan a gestionar las

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 sesion y si es necesario

tambien actualiza las cookies de su navegador. Ademas en ocasiones sera util por ejemplo

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 mantendra en todo

momento quien es el usuario real del sistema (el recepcionista) y quien es el usuario efectivo

(el cliente).

Esta clase sera en la que se apoyen los filtros de procesamiento a la hora de comprobar

si un usuario esta autenticado, si es el administrador o si es el recepcionista.

ReservationsManager La forma en la que se procesan las reservas hacen obligatorio

el guardar algunos datos a la espera de la confirmacion, de que se desea hacer, que estos

sean persistentes, en cuyo caso hay que pasar todos los datos a la fachada de gestion de

reservas o a la de gestion de reservas web para que estas se encarguen de su procesamiento

final.

Por ejemplo, cuando se realiza una nueva reserva, se le va preguntando al cliente que

introduzca los datos para reservar una habitacion, lo que se llama lınea de reserva en la

aplicacion, y una reserva contiene una o varias de estas lıneas, por lo que se ira preguntando

al cliente de hacer mas lı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

modificacion de una reserva es algo parecido, al cliente se le permite borrar las lıneas de

reserva que quiera y anadir otras nuevas, al terminar el cliente debe elegir si desea guardar

los cambios o no, en caso afirmativo todos los cambios se guardan juntos llamando a la

accion correspondiente de la fachada y ahorrando ası multiples accesos a la base de datos.

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 opcion de que cuando se

Page 134: Xesthproyecto

6.4. Arquitectura del Modelo 102

desea crear una oferta se pueda crear en ese instante un nuevo tipo de oferta. La creacion

de este nuevo tipo de oferta la hay que mantener en la cache a la espera de la confirmacion

de que se quiere crear la oferta, en caso afirmativo se crearan simultaneamente el nuevo

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 habitacion o se

modifican sus datos no hace falta realizarlo en varios pasos, pero sı hay que dar la opcion

de que cuando se desea crear una habitacion se pueda crear en ese instante un nuevo

tipo de habitacion. La creacion de este nuevo tipo la hay que mantener en la cache a

la espera de la confirmacion de que se quiere crear la habitacion, en caso afirmativo se

crearan simultaneamente el nuevo tipo y la nueva habitacion, pasando todos los datos

conjuntamente a la fachada del modelo.

6.4. Arquitectura del Modelo

Como ya se ha mencionado, el modelo es la parte de la aplicacion que implementa la

logica de negocio, es decir, es donde se decide como se llevaran a cabo todos los casos de

uso estudiados con anterioriad, que el sistema debe realizar.

Se comienza construyendo la base de datos, para que esta este construıda correctamente

antes se disena la misma en base a diagramas, donde se incluyen las relaciones que hay

entre las entidades que formaran la base de datos. Luego atendiendo a una serie de reglas

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 habra que

crear en la base de datos relacional.

Para desarrollar con mayor facilidad este proyecto, se ha dividido la aplicacion en dife-

rentes subsistemas, cada uno de ellos se encarga de un subconjunto de los casos de uso. Se

pretende que todos estos subsistemas sean lo mas independientes posible unos de otros,

y ademas se implementaran de forma que se pueda cambiar facilmente la base de datos

Page 135: Xesthproyecto

6.4. Arquitectura del Modelo 103

sobre la que se guarda la informacion, gracias al patron DAO usado para acceder a los

datos.

Para acceder a los distindos subsistemas, estos ofrecen una fachada con los metodos que

ofrecen, lo que permite cambiar la implentacion de dichos metodos cuando se desee sin

alterar las capas superiores de la aplicacion.

La arquitectura de los distintos sistemas es la misma para todos, de forma que en

primer lugar se hara una explicacion de los distintos patrones y arquitecturas usados, y

a continuacion se detallaran los diferentes subsistemas para comprobar como se utilizan

estos patrones.

Page 136: Xesthproyecto

6.4. Arquitectura del Modelo 104

6.4.1. Persistencia de los Datos

En este apartado se vera como se consigue desarrollar la base de datos en la que se

guardaran todos los datos de la aplicacion, a partir de las especificaciones iniciales.

En realidad este proyecto necesitara dos bases de datos distintas, una para guardar a los

usuarios, las habitaciones, las reservas y las facturas, y otra para guardar todo lo relacio-

nado con las ofertas. Gracias a esta separacion, si se desea modificar el esquema de gestion

de ofertas, solo se modificara una parte del sistema, que es totalmente independiente del

resto de la aplicacion.

A continuacion se detallara el proceso seguido para el diseno de cada una de las bases

de datos.

6.4.1.1. Base de Datos General

En esta base de datos se necesitara guardar a los distintos usuarios del sistema, estos

usuarios se identificaran mediante el DNI o el numero de Pasaporte, y de ellos se alma-

cenaran los siguientes datos: nombre, apellidos, fecha de nacimiento, direccion, paıs, dos

numeros de telefono y la direccion de correo electronico. Ademas se guardaran tambien el

nombre de usuario dentro del sistema y su contrasena cifrada, por otro lado, de un usuario

se tendra que poder saber si ya es cliente del hotel y si ha confirmado su identidad.

Por otro lado tambien se necesitan registrar las habitaciones que hay en el hotel, estas

se identificaran por su numero, y de ellas se mantendran almacenados el piso en el que

se encuentra y el posible precio extra que pueda tener. Cada habitacion sera de un solo

tipo, aunque en el futuro puede que se necesite que pueda ser de varios tipos distintos,

donde cada tipo se identifica por un numero generado y es el que define el precio base

de la habitacion, ademas se deben de almacenar la descripcion del tipo y el numero de

personas para las que se destina.

Page 137: Xesthproyecto

6.4. Arquitectura del Modelo 105

Como en una habitacion puede que ocurra algun tipo de percance, tambien se debe dar

soporte para registrar las distintas incidencias que puedan tener lugar en cada habitacion,

cada una de ellas se identificara por el numero de habitacion y por un identificador secun-

dario generado dinamicamente, de cada incidencia habra que mantener constancia de la

descripcion de la misma, el tipo (si es grave, leve, etc) y la fecha en la que se registra.

Para terminar, y como el cometido principal de la aplicacion es poder realizar reservas

de habitaciones, hay que dar soporte a esta opcion. Las reservas se identificaran por un

codigo de reserva y podran ser temporales o no, ademas habra que registrar la fecha en

la que se realiza. Luego una reserva podra contener una o varias lıneas de reserva cada

cual con relacion a una habitacion, por lo que estas lıneas se identificaran mediante el

numero de habitacion para la que se destinan y la fecha de llegada que se debe almacenar

en cada una, tambien se guardaran la fecha de salida, el total parcial que cuesta esa

estancia y el descuento ofrecido al aplicar las ofertas correspondientes. El total parcial

se almacena porque ademas de las reservas, las lıneas de reserva tambien estan presentes

en las facturas, por lo que una factura podra estar formada de igual forma por una o

varias lıneas de reserva. La factura se asociara a una persona, que sera quien debe pagarla

y se identificara por un numero de factura generado. En las facturas debe constar si ya

esta pagada, si aun esta como borrador, la fecha en la que se realiza el pago, el total que

forma la factura, el total parcial antes de aplicar las ofertas y las ofertas aplicadas.

El diseno se debe realizar para que si en un futuro se necesita, se pueda anadir por

ejemplo servicios extra, etc, y que estos puedan incluirse en la misma factura.

Despues de definir todo lo que se necesita almacenar, se procede a realizar el modelo

Entidad-Relacion, que es un diagrama mediante el cual se muestran los requisitos expre-

sados en los parrafos anteriores de forma gafica a traves de entidades, que son las ’cosas’

u ’objetos’ en el mundo real que se distinguen de todos los demas objetos, y relaciones,

las encargadas de mostrar como estan ligadas las distintas entidades unas con otras. Cada

entidad tendra una serie de propiedades especı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

Page 138: Xesthproyecto

6.4. Arquitectura del Modelo 106

la misma entidad a traves de uno o varios de los atributos, estos forman la denominada

’clave primaria’. En la pagina siguiente en la figura 6.8 se puede ver como queda el diseno

de esta base de datos a traves de un diagrama Entidad-Relacion.

Page 139: Xesthproyecto

6.4.A

rquitectu

radel

Modelo

107Figura 6.8: Diagrama Entidad Relacion - General

Page 140: Xesthproyecto

6.4. Arquitectura del Modelo 108

Una vez visto el diseno de la base de datos se procede a realizar el Modelo Relacional

de esta. El modelo relacional es un modelo de datos es una coleccion de herramientas

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 basica y unica para el almacenamiento de los datos es la ’relacion’. Ası, la base

de datos se representa como una coleccion de relaciones.

El modelo relacional de esta primera base de datos se puede ver representado en la figura

6.9

Figura 6.9: Modelo Relacional - General

Page 141: Xesthproyecto

6.4. Arquitectura del Modelo 109

Cuando se tiene el modelo relacional ya se pueden diferenciar las tablas que habra que

crear en la base de datos con sus claves primarias identificadas y tambien las claves

foraneas.

Para este proyecto se usara como base de datos MySQL, por defecto el motor de esta

base de datos es MyISAM. Este motor es rapido y eficiente. En un principio se penso en

utilizarlo, pero viendo que para realizar la persistencia de los datos de la aplicacion se

necesitan realizar transacciones, se opto por elegir un motor de base de datos que las

soportara. El motor elegido fue InnoDB que ademas de dar soporte para las transacciones

tambien soporta claves foraneas.

Finalmente y gracias al modelo relacional realizado ya se podra implementar la base de

datos, esta implementacion se muestra en el capıtulo 7 en la seccion 7.2.1.

6.4.1.2. Base de Datos de Ofertas

Esta base de datos se crea con motivo de dar soporte al que sera el sistema que gestione

las ofertas y sus combinaciones. Para que este sistema funcione correcta y eficientemente

es necesario que el diseno de la base de datos sea lo mas flexible posible y que cumpla

todos los requisitos del sistema.

Este sistema debe permitir definir ofertas de distintos tipos ya que de cada tipo, lue-

go, solo se podra aplicar una de ellas. Pero esto no es todo, ademas se podran definir

incompatibilidades entre ofertas, ası luego unicamente se aplicaran aquellas ofertas que

sean todas compatibles entre sı. Y por otro lado habra que indicar a que tipo de ventas

se podra aplicar la oferta (reservas, servicios extra, etc) y tambien se tendra que poder

definir una regla por la cual se restrinja a quien se le puede aplicar la oferta y a quien no.

Las ofertas se identificaran por un numero generado en el momento en la que se crean.

Cada oferta debera mantener los siguientes datos: Descripcion de la oferta, descuento que

se ofrece con esa oferta, la fecha a partir de la cual la oferta se comienza a aplicar y cuando

se termina de hacerlo, indicar si es un borrador y si esta desactivada. Ademas almacenara la

Page 142: Xesthproyecto

6.4. Arquitectura del Modelo 110

regla que se debe de cumplir para que se pueda aplicar, esta estara escrita en un lenguaje

de reglas que se definira posteriormente. Ademas cada oferta tendra un tipo de oferta,

estos tipos deberan guardar una descripcion y un nombre, y se identificaran mediante un

numero generado automaticamente. Luego estas ofertas podran ser incompatibles entre sı.

Cada oferta a su vez podra ser aplicada a una serie de productos, estas aplicaciones

se resolveran mediante un nombre del tipo de producto al que se aplicaran y la cantidad

mınima necesaria para que se aplique. En la figura 6.10 se puede ver como queda el diseno

de esta base de datos a traves de un diagrama Entidad-Relacion.

Figura 6.10: Diagrama Entidad Relacion - Ofertas

Page 143: Xesthproyecto

6.4. Arquitectura del Modelo 111

Una vez terminado el diseno de esta segunda base de datos se pasa a realizar el modelo

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 podran crear las tablas en la base de datos. La implementacion real de esta

base de datos se vera de forma mas detallada en el capıtulo 7 en la seccion 7.2.2.

6.4.2. Patrones Utilizados en el Modelo

6.4.2.1. Value Object (VO)

Este patron se utiliza cuando se necesita representar un conjunto de atributos proce-

dentes de uno o varios objetos del dominio, ademas, normalmente, representa en forma

de objeto del dominio a una entidad completa representada en la base de datos. Por esto

ultimo el patron VO se utiliza conjuntamente con el patron DAO que se explicara en la

siguiente seccion y que es el encargado de acceder a la base de datos y hacer persistentes

los atributos de los VO.

Page 144: Xesthproyecto

6.4. Arquitectura del Modelo 112

En la figura 6.12 se muestra la estructura basica de este patron.

<<interface>>java.io.Serializable

VO

+metodos get/set()

-atributos : ...

<<realize>>

<<interface>>DAO

<<call>>

Figura 6.12: Diagrama de Value Object

La clase VO de la figura es la que representa el objeto y ofrece metodos de lectura y

escritura para sus atributos. Este objeto debe implementar la interfaz Serializable ya que

esta, aunque simplemente es una interfaz marcadora, luego este objeto se podra transmitir

por red y reconstruir con facilidad gracias a un API que proporciona Java para convertir

automaticamente el estado de una instancia en un vector de bytes y viceversa.

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 aplicacion se usara la notacion xxxVO para estos objetos

6.4.2.2. Data Access Object (DAO)

El patron DAO es el encargado de abstraer el acceso a los datos. Esta arquitectura

ofrecera al programador una interfaz comun para acceder a la informacion, sin importar

ni como ni donde estan almacenados los datos. Ademas, ası se da la posibilidad de cambiar

la implementacion de acceso a la informacion cuando se desee. Para posibilitar este cambio,

se usa el patron Factory (Factorıa) que consta de una clase encargada de devolver un objeto

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,

Page 145: Xesthproyecto

6.4. Arquitectura del Modelo 113

una clase que a partir de una cadena devuelve el nombre de recurso deseado despues de

leerlo en un fichero de configuracion.

En la siguiente figura (6.13) se muestra como se estructuran las clases que dan forma

a este patron, y donde se incluye tambien el patron VO para que se vea claramente la

relacion de uno con otro.

DAOFactory

-DAOFactory()+getDAO() : DAO

-daoClass : Class

ConfigurationParametersManager

<<call>>

DAO

+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)

<<instantiate>>

VO

+metodos get/set()

-atributos : ...<<call>>

Figura 6.13: Diagrama de Data Access Object

Pero esta estructura aun se puede mejorar, como en este caso el volumen de datos no

sera pequeno, la informacion se almacenara en una base de datos relacional. Teoricamente

todas las bases de datos relacionales comprenden correctamente el lenguaje de consultas

SQL, pero en la practica esto no es ası, aunque SQL es un estandar cada fabricante tiene

sus pequenas variantes, lo que puede complicar un poco mas el diseno, ya que las sentencias

SQL que se escriban para hacer consultas sobre la base de datos variaran dependiendo de la

base de datos que se utilice. Las sencencias que sufren mayores variaciones entre fabricantes

son sobre todo las de insercion de datos, ya que para las sentencias de consultas simples

se utiliza el mismo SQL en todas las bases de datos.

Con el diseno anterior, si se quisiera cambiar de base de datos tendrıamos que modificar

la clase DAO, aunque solo se tuviese que cambiar la sentencia de insercion. Por este

motivo en el diseno utilizado se opto por separar la interfaz de acceso a los datos DAO

y su implementacion, de forma que se pudiese tener una implementacion abstracta de los

Page 146: Xesthproyecto

6.4. Arquitectura del Modelo 114

metodos comunes en todas las bases de datos, y redefinir exclusivamente aquellos que fuese

necesario, y en la figura 6.14 se puede ver como se organizan estas nuevas clases.

DAOFactory

-DAOFactory()+getDAO() : DAO

-daoClass : ClassConfigurationParametersManager

<<call>>

<<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)

<<instantiate>>

AbstractDAO

<<realize>>

SpecificDAO

VO

+metodos get/set()

-atributos : ...

Figura 6.14: Diagrama de Data Access Object Utilizado

Como se puede observar, todos los metodos necesitan recibir la conexion, esto se hace

para poder agrupar luego varias operaciones en una transaccion cuando sea necesario. La

clase DAO define una interfaz para insertar, borrar, buscar y actualizar objetos VO. Es-

te es un ejemplo de la aplicacion de otro patron simple, el Adapter (Adaptador), donde

DAOFactory permite obeter una instancia del adaptador que proceda para la aplicacion.

Gracias a este diseno, como ya se ha mencionado, es posible hacer ’plug-n-play’ de adap-

tadores sin tener que recompilar la aplicacion cuando se cambia de base de datos. En el

desarrollo del sistema se usara la notacion xxxDAO, xxx representara el nombre de la

entidad de la base de datos que corresponde al DAO en cuestion.

Page 147: Xesthproyecto

6.4. Arquitectura del Modelo 115

6.4.2.3. 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 metodos a las capas superiores, vista y controlador. Estas arquitecturas

se utilizan fundamentalmente para proporcionar una capa mas sencilla que de soporte para

implementar los casos de uso definidos, ocultando a su vez la tecnologıa utilizada.

El patron Session Facade es una aplicacion del patron Facade (Fachada) gracias al cual el

subsistema desarrollado resulta mas facil de utilizar por parte de capas superiores y reduce

el acoplamiento, de forma que la modificacion del subsistema no afecta a las otras capas

que lo utilicen. En este caso el Session Facade representa control y flujo, no persistencia,

de la cual ya se encargan los DAOs, ademas una Session Facade representa un conjunto de

casos de uso relacionados entre sı, y cada uno de estos conjuntos formaran un subsistema

de la aplicacion. En este caso se desarrollaran los siguientes Session Facades para imple-

mentar todos los subsistemas: ClientesFacade, FacturasWebFacade, HabitacionesFacade,

ReservasWebFacade, UsuariosWebFacade, OfertaFacade y TipoOfertaFacade.

Conjuntamente con el Session Facade se utiliza el patron Business Delegate, este sirve

para ocultar las tecnologıas utilizadas en el modelo, normalemente un objeto Business

Delegate oculta a un Session Facade, pero en este caso seran el mismo, y aunque no

sera necesario dar la opcion de cambiar la tecnologıa usada, por ejemplo utilizar EJB, si

en el futuro se desea hacer este cambio se hara de forma sencilla. Como en el sistema solo

habra un Business Delegate por subsistema se denotara por GeneralXxxFacade.

Para dar soporte a las consultas a la base de datos, hay que recordar que los DAO

necesitaban que se les proveera de una conexion para ejecutar las consultas, se tiene una

clase de utilidad, en este caso SimpleDataSource, que valdra para crear una conexion nueva

a la base de datos y devolverla.

Tambien hay que dar solucion a unos problemas. El primero que se encuentra es que

un Session Facade puede tener mas de 10 operaciones, lo que desembocarıa en una clase

muy grande. Para solucionar este primer contratiempo se hara que cada operacion se

Page 148: Xesthproyecto

6.4. Arquitectura del Modelo 116

implemente en una clase, se denominaran clases Action, con esto lo que se consigue es que el

Session Facade delegue la implementacion de cada operacion en la Action correspondiente.

La organizacion de las distintas clases de este conjunto de patrones se puede ver en la figura

6.15

<<interface>>XxxFacade

GeneralXxxFacade

+GeneralXxxFacade()

-dataSource : DataSource

<<realize>>

Actions

<<call>>

PlainActionProcessor

<<call>>

SimpleDataSource

+getConnection() : Connection

<<call>>

Figura 6.15: Diagrama de Session Facade y Business Delegate

Como segundo problema esta la transaccionalidad necesaria en muchas de las acciones

aunque otras no lo necesiten. Las acciones transaccionales deberan solicitar una conexion

al inicio de la operacion y cerrarla al terminar. La resolucion de este ultimo problema se

logra utilizando el procesador de acciones, en este caso PlainActionProcessor, lo unico que

hay que conseguir es que teniendo dos metodos, uno para procesar las acciones transac-

cionales y otro para procesar las que no lo son, las acciones transaccionales las procese

automaticamente el metodo que corresponde y lo mismo para las no transaccionales.

El procesador de acciones que se ve en la figura 6.15 necesita que las acciones implemen-

ten una interfaz PlainAction, para desta forma identificarlas y poder llamar a su metodo

execute(). Esta opcion, es la que se aprovecha para diferenciar las acciones transacciona-

les, se crean dos nuevas interfaces que heredan de PlainAction: TransactionalPlainAction

y NonTransactionalPlainAction. Ası las acciones que implementen cualquiera de estas dos

nuevas interfaces estaran implementando tambien la interfaz PlainAction, como bien se

puede ver en la figura 6.16. Las interfaces que se crean se denominan Markers (Marcado-

Page 149: Xesthproyecto

6.4. Arquitectura del Modelo 117

res) ya que no tienen la firma de ningun metodo y simplemente sirven para diferenciar

unas clases de otras, en este caso las que implementan una transaccion y las que no.

PlainActionProcessor

-PlainActionProcessor()+process(dataSource : DataSource,action : NonTransactionalPlainAction) : Object+process(dataSource : DataSource,action : TransactionalPlainAction) : Object

<<interface>>PlainAction

+execute(c : Connection) : Object

<<call>>

<<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 informacion guardada en la base de datos y modificarla si fuera necesa-

rio, Java proporciona un API JDBC para realizarlo. Ademas en este proyecto se utilizara el

patron DAO explicado en la seccion 6.4.2.2. Para simplificar el trabajo, se construira un

objeto DAO por cada entidad y relacion de la base de datos, esto es, un DAO por cada

tabla de la base de datos. Los objetos DAO tendran metodos de creacion de nuevos valores

en la base de datos, eliminacion, modificacion y consulta de datos segun algunos parame-

tros que se proporcionen. Aunque se implementaran todos los metodos que se puedan

necesitar, luego no se usaran todos, pero los objetos DAO ya quedarıan preparados por si

en el futuro se necesitasen realizar otras consultas. Los objetos DAO utilizan los objetos

VO relacionados con ellos, por lo que tambien se creara un objeto VO por cada una de

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

Page 150: Xesthproyecto

6.4. Arquitectura del Modelo 118

Figura 6.17: Estructura de los paquetes DAO y VO

xxx

DAO

VO

xxxVO

SQLxxxDAOFactory

AbstractSQLxxxDAO

<<interface>>SQLxxxDAO

<<realize>>

<<instantiate>>

MySQLxxxDAO

Figura 6.18: Diagrama General de los DAO

Y a continuacion se muestran los diagramas de todos los DAOs de esta aplicacion,

clasificados segun el paquete en el que se encuentran. La estructura es la misma para

todos, pero los metodos que ofrecen no lo son. Las clases MySQLxxDAO se utilizan para

redefinir el metodo de creacion de datos, ya que si luego se desea cambiar de gestor de base

de datos, las sentencias de consulta en SQL normalmente son iguales en todos los gestores,

pero las de insercion no, sobre todo a la hora de generar las claves. En caso de que esto

suceda, simplemente habrıa que cambiar la clase MySQLxxxDAO por la que corresponda

para el nuevo gestor de base de datos.

Page 151: Xesthproyecto

6.4. Arquitectura del Modelo 119

6.4.3.1. Paquete ’persona’

<<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

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

<<realize>>

MySQLPersonaDAO

+addPersona(connection : Connection,personaVO : PersonaVO) : PersonaVO

SQLPersonaDAOFactory

<<create>> -SQLPersonaDAOFactory()-getDAOClass() : Class+getDAO() : SQLPersonaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

hotel::modelo::persona::vo::PersonaVO

-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

<<call>>

<<call>>

Figura 6.19: Diagrama del Paquete ’persona’

Page 152: Xesthproyecto

6.4. Arquitectura del Modelo 120

6.4.3.2. Paquete ’tipohabitacion’

SQLTipoHabitacionDAOFactory

<<create>> -SQLTipoHabitacionDAOFactory()-getDAOClass() : Class+getDAO() : SQLTipoHabitacionDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

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’

Page 153: Xesthproyecto

6.4. Arquitectura del Modelo 121

6.4.3.3. Paquete ’habitacion’

SQLHabitacionDAOFactory

<<create>> -SQLHabitacionDAOFactory()-getDAOClass() : Class+getDAO() : SQLHabitacionDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

MySQLHabitacionDAO

+addHabitacion(connection : Connection,habitacionVO : HabitacionVO) : HabitacionVO

HabitacionVO

-serialVersionUID : long-numero : Long-piso : Long-precioExtra : Double

Figura 6.21: Diagrama del Paquete ’habitacion’

Page 154: Xesthproyecto

6.4. Arquitectura del Modelo 122

6.4.3.4. Paquete ’esdetipo’

SQLEsDeTipoDAOFactory

<<create>> -SQLEsDeTipoDAOFactory()-getDAOClass() : Class+getDAO() : SQLEsDeTipoDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

MySQLEsDeTipoDAO

+addEsDeTipo(connection : Connection,esDeTipoVO : EsDeTipoVO) : EsDeTipoVO

EsDeTipoVO

-serialVersionUID : long-numero : Long-idTipo : Long

Figura 6.22: Diagrama del Paquete ’esdetipo’

Page 155: Xesthproyecto

6.4. Arquitectura del Modelo 123

6.4.3.5. Paquete ’incidencia’

SQLIncidenciaDAOFactory

<<create>> -SQLIncidenciaDAOFactory()-getDAOClass() : Class+getDAO() : SQLIncidenciaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

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’

Page 156: Xesthproyecto

6.4. Arquitectura del Modelo 124

6.4.3.6. Paquete ’lineadereserva’

SQLLineaDeReservaDAOFactory

<<create>> -SQLLineaDeReservaDAOFactory()-getDAOClass() : Class+getDAO() : SQLLineaDeReservaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

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’

Page 157: Xesthproyecto

6.4. Arquitectura del Modelo 125

6.4.3.7. Paquete ’reserva’

SQLReservaDAOFactory

<<create>> -SQLReservaDAOFactory()-getDAOClass() : Class+getDAO() : SQLReservaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

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’

Page 158: Xesthproyecto

6.4. Arquitectura del Modelo 126

6.4.3.8. Paquete ’factura’

SQLFacturaDAOFactory

<<create>> -SQLFacturaDAOFactory()-getDAOClass() : Class+getDAO() : SQLFacturaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

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’

Page 159: Xesthproyecto

6.4. Arquitectura del Modelo 127

6.4.3.9. Paquete ’tipooferta’

SQLTipoOfertaDAOFactory

<<create>> -SQLTipoOfertaDAOFactory()-getDAOClass() : Class+getDAO() : SQLTipoOfertaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

MySQLTipoOfertaDAO

+addTipoOferta(connection : Connection,tipoOfertaVO : TipoOfertaVO) : TipoOfertaVO

TipoOfertaVO

-serialVersionUID : long-idTipo : Long-nombre : String-descripcion : String

Figura 6.27: Diagrama del Paquete ’tipooferta’

Page 160: Xesthproyecto

6.4. Arquitectura del Modelo 128

6.4.3.10. Paquete ’oferta’

SQLOfertaDAOFactory

<<create>> -SQLOfertaDAOFactory()-getDAOClass() : Class+getDAO() : SQLOfertaDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

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

<<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>>

Figura 6.28: Diagrama del Paquete ’oferta’

Page 161: Xesthproyecto

6.4. Arquitectura del Modelo 129

6.4.3.11. Paquete ’aplicablea’

SQLAplicableADAOFactory

<<create>> -SQLAplicableADAOFactory()-getDAOClass() : Class+getDAO() : SQLAplicableADAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

MySQLAplicableADAO

+addAplicableA(connection : Connection,aplicableAVO : AplicableAVO) : AplicableAVO

AplicableAVO

-serialVersionUID : long-idTipo : Long-nombre : String-cantidadMin : Long

Figura 6.29: Diagrama del Paquete ’aplicablea’

Page 162: Xesthproyecto

6.4. Arquitectura del Modelo 130

6.4.3.12. Paquete ’incompatiblecon’

SQLIncompatibleConDAOFactory

<<create>> -SQLIncompatibleConDAOFactory()-getDAOClass() : Class+getDAO() : SQLIncompatibleConDAO

-DAO_CLASS_NAME_PARAMETER : String-daoClass : Class

<<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

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

<<realize>>

MySQLIncompatibleConDAO

+addIncompatibleCon(connection : Connection,incompatibleConVO : IncompatibleConVO) : IncompatibleConVO

IncompatibleConVO

-serialVersionUID : long-idTipo : Long-idTipoIncomp : Long

Figura 6.30: Diagrama del Paquete ’incompatiblecon’

Page 163: Xesthproyecto

6.4. Arquitectura del Modelo 131

6.4.4. Descripcion de los Subsistemas

En los siguientes apartados se detallaran todos los subsistemas que forman la aplicacion.

El primer subsistema que se tratara sera el de gestion de Usuarios y Clientes, encargado

de dar de alta, baja, modificacion de datos, busqueda de clientes, etc. Este subsistema

junto con el de Reservas son los dos que se desarrollan en la primera iteracion de la fase de

construccion durante la implementacion. Un vez desarrollados estos dos sistemas se tiene

una primera version del software que ya se puede utilizar y probar.

En una segunda iteracion se implementa el subsistema de Gestion de Facturas, ya que

esta muy relacionado con la Gestion de Reservas. Sin embargo este sistema utiliza el

Sistema de Ofertas del que se habla en la pagina 166, por lo que, aunque se implementa

mas tarde, ya habra que definir en un principio la interfaz que va a utilizar para ofrecer

servicios a los subsistemas.

En la siguiente iteracion se desarrollara el subsistema de Gestion de Ofertas, que ya que

tambien esta relacionado con el de las Facturas, es una buena idea implementarlo en este

punto.

Por ultimo se desarrollara la Gestion de Habitaciones, que aunque es un sistema que no

es complicado, no se puede dejar atras.

6.4.4.1. Gestion de Usuarios y Clientes

En esta seccion se mostrara como es el desarrollo de los casos de uso Gestion de Usuarios

Web y Gestion de Clientes. Como se ha podido observar en la descripcion de estos casos de

uso, los dos conjuntos de casos son muy parecidos, simplemente cambian algunos apartados

de los casos de uso o se anaden otros nuevos, y los actores que los llevan a cabo. Por

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 patron Session Facade en ambos conjuntos de casos de uso.

Page 164: Xesthproyecto

6.4. Arquitectura del Modelo 132

De aquı en adelante se mostrara como se organizan las clases que forman este subsistema

y luego se aclarara el cometido que tiene cada una de ellas. En las figuras 6.31 y 6.32

se muestra unos diagramas sencillos de la Gestion de Usuarios y en las 6.33 y 6.34 los

diagramas de la Gestion de Clientes.

<<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

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

<<realize>>

actions

exceptions

Figura 6.31: Diagrama Simple de Gestion de Usuarios

AltaUsuarioAction

<<create>> +AltaUsuarioAction(personaVO : PersonaVO)+execute(connection : Connection) : Object

AutenticarAction

<<create>> +AutenticarAction(userName : String,userPassword : String)+execute(connection : Connection) : Object

BajaUsuarioAction

<<create>> +BajaUsuarioAction(dniPas : String)+execute(connection : Connection) : Object

GetDatosAction

<<create>> +GetDatosAction(dniPasPersona : String)+execute(connection : Connection) : Object

ModificarDatosUsuarioAction

<<create>> +ModificarDatosUsuarioAction(personaVO : PersonaVO)+execute(connection : Connection) : Object

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>TransactionalPlainAction

<<interface>>NonTransactionalPlainAction

AuthenticationFailException

PersonAlreadyExistsException

UserNameAlreadyInUseException

Figura 6.32: Actions y Exceptions de Gestion de Usuarios

Page 165: Xesthproyecto

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 terminos de DAOs. Esta fachada

proporciona a las demas capas que la quieran utilizar una serie de operaciones. Estas

operaciones que ofrece, para evitar caer en una clase enorme, delegan su funcionamiento

en las acciones correspondientes del subpaquete Actions. A continuacion se explicara el

funcionamiento de cada una de las acciones.

Ademas de usar unas acciones para implementar sus metodos, esta fachada tambien

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 emplearan para proporcionar informacion a las capas superiores acerca del estado

con el que finalizo la operacion, sin que este estado tenga que ser un estado de error de

la aplicacion. En el caso de UsuariosWebFacade se utilizaran excepciones para informar si

el nombre de usuario esta en uso, si la autenticacion ha sido fallida y si el usuario que se

pretende crear o modificar ya existe en el sistema.

Las acciones en base a las cual se implementan las operaciones de UsuariosWebFacade,

podran clasificarse como transaccionales y no transaccionales dependiendo si es necesario

que la operacion se realice de forma atomica o no, y son las siguientes:

AltaUsuarioAction Esta accion es la encargada de dar de alta un nuevo usuario

en el sistema. Para ello necesita que se le pasen los parametros necesarios para

tal operacion, es decir, los datos del nuevo usuario, estos iran encapsulados

en un objeto PersonaVO, que como ya se ha visto anterioremente, sigue el

patron Value Object (VO) y proporciona metodos para lectura y escritura de

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 metodos para

insertar, modificar, consultar y eliminar datos de la base de datos. Si el DNI

Page 166: Xesthproyecto

6.4. Arquitectura del Modelo 134

ya existe se lanzara una excepcion indicando este suceso, y si no se continua

comprobando si existe el nombre de usuario, si no existe entonces se procede

a la insercion de los datos del nuevo usuario en la base de datos utilizando

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 estan almacenados y se comparan

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 informacion.

A continuacion se recuperan los datos del usuario que estan almacenados.

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 operacion necesita el nombre de usuario y la contrasena del cliente.

Lo primero que realiza la accion es recuperar los datos de un usuario que tenga

ese nombre de usuario y esa contrasena, si la recuperacion falla o el usuario

esta senalado como ’no confirmado’ entonces se lanza la excepcion Autentica-

tionFailException, que indica que no se pudo autenticar la identidad del cliente.

Page 167: Xesthproyecto

6.4. Arquitectura del Modelo 135

A continuacion en la figura 6.33 se muestra el esquema de las clases que forman el Session

Facade ’ClientesFacade’ y las acciones en las que sus metodos delegan su funcionamiento.

<<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

GeneralClientesFacade

<<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

-serialVersionUID : long-dataSource : DataSource-personaVO : PersonaVO

<<realize>>

actions exceptions vo

Figura 6.33: Diagrama Simple de Gestion de Clientes

Page 168: Xesthproyecto

6.4. Arquitectura del Modelo 136

AltaClienteAction

<<create>> +AltaClienteAction(personaVO : PersonaVO)+execute(connection : Connection) : Object

BajaClienteAction

<<create>> +BajaClienteAction(dniPas : String)+execute(connection : Connection) : Object

BuscarClientesAction

<<create>> +BuscarClientesAction(name : String,surname : String,dniPas : String,startIndex : int,count : int)+execute(connection : Connection) : Object

GetDatosAction

<<create>> +GetDatosAction(dniPasPersona : String)+execute(connection : Connection) : Object

ModificarDatosClienteAction

<<create>> +ModificarDatosClienteAction(personaVO : PersonaVO)+execute(connection : Connection) : Object

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>NonTransactionalPlainAction

<<interface>>TransactionalPlainAction

PersonAlreadyExistsException

PersonNotFoundException UserNameAlreadyInUseException

PersonaCollectionChunkVO

<<create>> +PersonaCollectionChunkVO(colPersonas : Collection,index : int,more : Boolean)+getColPersonas() : Collection+getIndex() : int+getHasMore() : Boolean

<<call>>

<<create>>

Figura 6.34: Actions y Exceptions de Gestion de Clientes

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, im-

plementado por GeneralClientesFacade. Al igual que en el Session Facade anterior, los

metodos de la fachada delegan su funcionamiento en las acciones correspondientes del

subpaquete Actions. A continuacion se explicara el funcionamiento de cada una de las

acciones.

Ademas de usar unas acciones para implementar sus metodos, esta fachada tambien

lanza CustomException para proporcionar informacion a las capas superiores acerca del

estado con el que finalizo la operacion. En este caso se usaran excepciones para informar si

el nombre de usuario del cliente esta en uso, si el cliente que se pretende crear o modificar

ya existe en el sistema, o si un cliente buscado no se ha encontrado.

Page 169: Xesthproyecto

6.4. Arquitectura del Modelo 137

Las acciones en base a las cual se implementan las operaciones de ClientesFacade, tam-

bien podran clasificarse como transaccionales y no transaccionales dependiendo si es ne-

cesario que la operacion se realice de forma atomica o no, y son las siguientes:

AltaClienteAction Esta accion es la encargada de dar de alta un nuevo cliente

en el sistema. Para ello necesita que se le pasen los parametros necesarios para

tal operacion, es decir, los datos del nuevo cliente, estos iran encapsulados en

un objeto PersonaVO, que como ya se ha visto anterioremente, aunque para el

caso de dar de alta un nuevo cliente no seran obligatorios todos los datos que

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 lanzara una excepcion

indicando este suceso, y sino se continua comprobando si existe el nombre de

usuario, si no existe entonces se procede a la insercion de los datos del nuevo

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 excepcion, y 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 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 estan almacenados y se comparan

uno a uno con los nuevos, aquellos que no coincidan se actualizan utilizando

PersonaDAO.

Page 170: Xesthproyecto

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 informacion.

A continuacion se recuperan los datos del cliente que estan almacenados.

BuscarClientesAction Esta accion es la encargada de recuperar una lista de clien-

tes que concuerden con unos parametros de busqueda, en este caso se podra bus-

car por nombre, apellidos y/o DNI, se podra hacer cualquier combinacion que

se desee.

Para llevar a cabo esta operacion es necesario comprobar cuales son los campos

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 rea-

lizar la consulta. Una vez hecho esto PersonaDAO recupera la lista de clientes

que concuerdan con los criterios.

6.4.4.2. Gestion de Reservas

En esta seccion se mostrara como es el desarrollo de los casos de uso Gestion de Reservas.

Como en los casos anteriores se utiliza el patron Session Facade para implementar este

subsistema.

Entre las operaciones de este sistema cabe destacar que debe permitir comprobar si existe

alguna habitacion libre de un tipo determinado para una serie de dıas. Esta operacion no

implementa ningun caso de uso especıfico pero es necesaria para realizar comprobaciones

a la hora de realizar reservas.

De aquı en adelante se mostrara como se organizan las clases que forman este subsistema

y luego se aclarara el cometido que tiene cada una de ellas. En las figuras 6.35 y 6.36 se

muestra unos diagramas sencillos de la Gestion de Reservas.

Page 171: Xesthproyecto

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

GeneralReservasWebFacade

<<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

-dataSource : DataSource

<<realize>>

actions

vo

exceptions

LineaDeReservaChunkVO

ReservaChunkVOReservaCompletaChunkVO

ReservaFromToTipoHabitacionChunkVO

ReservasCollectionChunkVO

Figura 6.35: Diagrama Simple de Gestion de Reservas

Page 172: Xesthproyecto

6.4. Arquitectura del Modelo 140

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>TransactionalPlainAction

<<interface>>NonTransactionalPlainAction

CrearReservaAction

<<create>> +CrearReservaAction(dniPas : String,reserva : Collection)+execute(connection : Connection) : Object

ModificarReservaAction

<<create>> +ModificarReservaAction(lastReserva : ReservaCompletaChunkVO,newReserva : ReservaCompletaChunkVO)+execute(connection : Connection) : Object

CheckDisponibleAction

<<create>> +CheckDisponibleAction(reserva : ReservaFromToTipoHabitacionChunkVO)+execute(connection : Connection) : Object

CheckDisponibleQuantityAction

<<create>> +CheckDisponibleQuantityAction(reserva : ReservaFromToTipoHabitacionChunkVO,quantity : Long)+execute(connection : Connection) : Object

CheckHabitacionesLibresAction

<<create>> +CheckHabitacionesLibresAction(from : Calendar,to : Calendar)+execute(connection : Connection) : Object

GetReservaCompletaAction

<<create>> +GetReservaCompletaAction(codReserva : Long)+execute(connection : Connection) : Object

GetReservasAction

<<create>> +GetReservasAction(dniPas : String,index : int,count : int)+execute(connection : Connection) : Object

EmptyReservationException

IllegalCheckException

IllegalReservationChangeException

NoReservationFoundException

NoRoomsOfEspecifiedTypeException

SomeDayNotAvailableException

Figura 6.36: Actions y Exceptions de Gestion de Reservas

Page 173: Xesthproyecto

6.4. Arquitectura del Modelo 141

En estos diagramas se puede ver como se vuelven a usar los patrones Session Facade

y Business Delegate. La interfaz para acceder a este subsistema es ReservasWebFacade,

implementado por GeneralReservasWebFacade. Al igual que en el Session Facade anterior,

los metodos de la fachada delegan su funcionamiento en las acciones correspondientes del

subpaquete Actions. A continuacion se explicara el funcionamiento de cada una de las

acciones.

Ademas de usar unas acciones para implementar sus metodos, esta fachada tambien

lanza CustomException para proporcionar informacion a las capas superiores acerca del

estado con el que finalizo la operacion. En este caso se usaran excepciones para informar

si no hay habitaciones libres de un tipo solicitado, si una reserva que se desea crear o

modificar esta vacıa, si se quiere crear o cambiar una reserva pero alguno de los dıas

esta ya ocupado, si una reserva no se puede cambiar o si no se encuentra una reserva

buscada.

Por otro lado, esta fachada manejara unos objetos especiales, los Custom Value Objects.

Estos objetos estaran localizados en el subpaquete ’vo’ y tendran como cometido ofrecer

a las capas superiores un conjunto de los atributos de un VO ya existente, o varios atri-

butos 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 encapsularan en un objeto que ademas contendra otra

informacion como: si hay, o no, mas elementos para hacer una siguiente busqueda.

Las acciones en base a las cuales se implementan las operaciones de ReservasFacade,

tambien podran clasificarse como transaccionales y no transaccionales dependiendo si es

necesario que la operacion se realice de forma atomica o no, y son las siguientes:

CrearReservaAction Esta accion es la encargada de crear una nueva reserva. Para

esto necesita que se le pasen un conjunto de lıneas de reserva y el DNI del cliente

que la desea realizar.

Page 174: Xesthproyecto

6.4. Arquitectura del Modelo 142

Las lıneas de reserva que se le deben pasar a esta accion tienen que ser lo menos

concretas posibles, es decir, no se indicara la habitacion, ya que estas se asignan

una vez que se comprueben si estan libres. Para pasar estos datos se crea un

nuevo objeto que es ’ReservaFromToTipoHabitacionChunkVO’ que lo unico

que representa es: una fecha de llegada, fecha de salida y tipo de habitacion

al que se destina. Este objeto tambien proporcionara metodos necesarios para

comprobar si una reserva coincide en fechas con otra.

Luego la accion tiene que comprobar si hay habitaciones libres de alguna ha-

bitacion del tipo deseado para los dıas indicados. Si es ası, se escoge alguna

de las habitaciones libres para los dıas que se desean y se guarda la lınea de

reserva. Esto se hace con todas las lıneas de reserva y a continuacion se crean:

una nueva factura calculando todos los totales y una reserva.

Al terminar se devuelve un objeto ’ReservaCompletaChunkVO’ donde se encap-

sulan todas las lıneas de reserva, los datos de la reserva, numero de la factura,

etc.

ModificarReservaAction Esta accion hace lo mismo que ’CrearReservaAction’,

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ıan y hay que eliminar. Una vez hechas esas comprobaciones y

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 codigo de la reserva. Luego la accion,

utilizando los DAOs pertinentes, recupera las lıneas de reserva, los datos de la

reserva y los datos de la factura. A continuacion lo encapsula todo en un objeto

’ReservaCompletaChunkVO’ y lo devuelve.

Page 175: Xesthproyecto

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 donde se desea recuperar

la lista de reservas y cuantas se quiere que se devuelvan.

Con estos datos, la accion consigue de la base de datos las reservas deseadas y

las encapsula en un objeto ’ReservasCollectionChunkVO’ que sera el que se le

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 accion es la encargada de comprobar si hay habita-

ciones libres para un rango de fechas determinado y para un tipo de habitacion.

Para esto se le debe pasar un objeto ’ReservaFromToTipoHabitacionChunkVO’

que contiene las fechas y el tipo de habitacion que se quiere comprobar.

La accion comprueba si para los dıas indicados existe alguna habitacion que no

este ocupada, de ser ası devuelve un valor de tipo ’boolean’ indicando que hay

al menos una habitacion disponible de ese tipo para esas fechas.

CheckDisponibleQuantityAction Esta accion es la encargada de comprobar si

hay habitaciones libres para un rango de fechas, para un tipo de habitacion y

una cantidad determinada. Para esto se le debe pasar un objeto ’ReservaFrom-

ToTipoHabitacionChunkVO’ que contiene las fechas, el tipo de habitacion que

se quiere comprobar y el numero de habitaciones que se desean.

La accion comprueba si para los dıas indicados existe el numero de habitaciones

indicado que no esten ocupadas, de ser ası devuelve un valor de tipo ’boolean’

indicando que hay al menos ese numero de habitaciones disponibles de ese tipo

para esas fechas.

CheckHabitacionesLibresAction Esta accion es la encargada de comprobar cuantas

habitaciones hay libres para un rango de fechas. Se le pasa una fecha de llegada

y una de salida.

Page 176: Xesthproyecto

6.4. Arquitectura del Modelo 144

Luego comprueba para todos los tipos de habitaciones cuantas hay libres para

esas fechas y devuelve un conjunto de tipos de habitacion y numero de habita-

ciones libres.

6.4.4.3. Gestion de Habitaciones

En esta seccion se mostrara como es el desarrollo de los casos de uso Gestion de Habita-

ciones. Como en los casos anteriores se utiliza el patron Session Facade para implementar

este subsistema.

De aquı en adelante se mostrara como se organizan las clases que forman este subsistema

y luego se aclarara el cometido que tiene cada una de ellas. En las figuras 6.37 y 6.38 se

muestra unos diagramas sencillos de la Gestion de Habitaciones.

Page 177: Xesthproyecto

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

GeneralHabitacionesFacade

<<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

-dataSource : DataSource

<<realize>>

actions exceptionsvo

HabitacionCompletaChunkVO

HabitacionesCollectionChunkVO

IncidenciasCollectionChunkVO

Figura 6.37: Diagrama Simple de Gestion de Habitaciones

Page 178: Xesthproyecto

6.4. Arquitectura del Modelo 146

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>NonTransactionalPlainAction

<<interface>>TransactionalPlainAction

AddIncidentAction

<<create>> +AddIncidentAction(incidencia : IncidenciaVO,number : Long)+execute(connection : Connection) : Object

AddRoomAction

<<create>> +AddRoomAction(habitacion : HabitacionVO,idTipo : Long)+execute(connection : Connection) : Object

AddRoomCompleteAction

<<create>> +AddRoomCompleteAction(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO)+execute(connection : Connection) : Object

AddRoomTypeAction

<<create>> +AddRoomTypeAction(tipoHabitacion : TipoHabitacionVO)+execute(connection : Connection) : Object

DeleteRoomAction

<<create>> +DeleteRoomAction(number : Long)+execute(connection : Connection) : Object

GetAllIncidentsOfRoomAction

<<create>> +GetAllIncidentsOfRoomAction(number : Long,index : int,count : int)+execute(connection : Connection) : Object

GetAllRoomsAction

<<create>> +GetAllRoomsAction(index : int,count : int)+execute(connection : Connection) : Object

GetAllRoomTypesAction

<<create>> +GetAllRoomTypesAction()+execute(connection : Connection) : Object

GetIncidentAction

<<create>> +GetIncidentAction(number : Long,idInc : Long)+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

UpdateRoomAction

<<create>> +UpdateRoomAction(habitacion : HabitacionVO,idTipo : Long)+execute(connection : Connection) : Object

UpdateRoomCompleteAction

<<create>> +UpdateRoomCompleteAction(habitacion : HabitacionVO,tipoHabitacion : TipoHabitacionVO)+execute(connection : Connection) : Object

UpdateRoomTypeAction

<<create>> +UpdateRoomTypeAction(tipoHabitacion : TipoHabitacionVO)+execute(connection : Connection) : Object

Figura 6.38: Actions de Gestion de Habitaciones

Page 179: Xesthproyecto

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 Habita-

cionesFacade, implementado por GeneralHabitacionesFacade. Al igual que en los Session

Facade anteriores, los metodos de la fachada delegan su funcionamiento en las acciones

del subpaquete Actions. A continuacion se explicara el funcionamiento de cada una de las

acciones.

Ademas de usar unas acciones para implementar sus metodos, esta fachada tambien

lanzara CustomException para proporcionar informacion a las capas superiores acerca del

estado con el que finalizo la operacion. En este caso se usaran excepciones para informar

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 Gestion de Reserva, esta fachada tambien manejara unos

objetos especiales, los Custom Value Objects. Este tipo de objetos, cuyo uso y cometido ya

se ha mencionado en la explicacion del subsistema anterior, se encontraran en el subpaquete

’vo’.

Las acciones en base a las cuales se implementan las operaciones de HabitacionesFacade,

se podran clasificar como transaccionales y no transaccionales como ocurrıan en los demas

subsistemas. Estas acciones se explicaran a continuacion muy brevemente debido a que no

implementan procesos complejos:

AddRoomTypeAction Esta accion se encarga de crear un nuevo tipo de habita-

cion. Para ello se le pasan los datos del nuevo tipo de habitacion y utilizando

los DAOs pertinentes inserta el nuevo tipo en la base de datos.

AddRoomAction Al igual que la accion anterior, se encarga de crear una nueva

habitacion. Para esto necesita que se le pasen los datos de la habitacion y el

tipo de habitacion al que pertenecera.

Primero se comprueba que el tipo de habitacion exista, si existe se guardan los

datos de la nueva habitacion, y sino se lanza una exepcion indicando que el tipo

de habitacion no se ha encontrado.

Page 180: Xesthproyecto

6.4. Arquitectura del Modelo 148

AddRoomCompleteAction A veces puede que se quiera crear una habitacion y

el tipo de habitacion en el mismo momento. Esta accion da soporte para que

eso se pueda realizar. Como se puede adivinar, en este caso se necesitaran los

datos de la habitacion y del tipo de habitacion.

Primero se intenta crear el tipo de habitacion, si el tipo existe, se lanza una

excepcion para indicarlo, y sino, se procede a insertar los datos de la nueva

habitacion.

AddIncidentAction Si ocurriese algun percance en una de las habitaciones habrıa

que registrarlo, esta accion permite guardar un incidente y relacionarlo con una

habitacion. Para realizarlo se le deben pasar los datos del incidente y el numero

de habitacion en la que ha ocurrido.

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 habi-

tacion. Se le deben indicar los nuevos datos.

Primero se recuperan los datos almacenados, luego se comparan con los datos

antiguos y solo se actualizan los que difieran.

UpdateRoomAction Se encarga de actualizar los datos de una habitacion. Se le

deben indicar los nuevos datos y el nuevo tipo de habitacion.

Primero se recuperan los datos almacenados, luego se comprueba si se debe

actualizar el tipo de habitacion, y a continuacion se comparan los nuevos datos

con los antiguos y solo se actualizan los que difieran.

UpdateRoomAction Se encarga de actualizar los datos de una habitacion y de

crear un nuevo tipo de habitacion para esta. Se le deben indicar los nuevos

datos de la habitacion y los del tipo de habitacion.

Page 181: Xesthproyecto

6.4. Arquitectura del Modelo 149

Primero se recuperan los datos almacenados, luego se crea el nuevo tipo de

habitacion, y a continuacion se comparan los nuevos datos con los antiguos y

solo se actualizan los distintos.

DeleteRoomAction Esta accion es la encargada de eliminar una habitacion de la

base de datos. Simplemente le hay que pasar el numero de la habitacion que se

quiere borrar. Si la habitacion no existe se lanza una excepcion indicandolo, y

sino se utiliza el DAO pertinente para eliminarla.

GetAllIncidentsOfRoomAction Con esta accion se permite recuperar una lista

de los incidentes de una habitacion. Para ello hay que pasarle el numero de

habitacion de la cual se desean los incidentes, desde donde se quiere que se

recuperen y la cantidad.

A continuacion la accion recupera los datos a traves de los DAOs y los encapsula

en un Custom Value Object, de esta forma, como ya se ha visto con las reservas,

se consigue una paginacion de los resultados.

GetIncidentAction Esta accion es la encargada recuperar los datos de un inci-

dente. Para ello se le debe pasar la habitacion donde tuvo lugar y el numero de

incidente. Con estos datos lo recupera y lo devuelve.

GetAllRoomTypesAction Con esta accion se permite recuperar una lista de los

tipos de habitacion.

La accion simplemente recupera todos los tipos de habitacion y los devuelve a

traves de un objeto Collection. Esta vez no necesitan ser paginados porque se

estiman pocos y se puede permitir enviarlos todos juntos.

GetRoomTypeAction Esta accion se encarga de recuperar los datos de un tipo

de habitacion. Para ello hay que pasarle el identificador del tipo de habitacion

del que se quieren los datos. La accion recupera los datos mediante los DAOs

pertinentes y los devuelve.

Page 182: Xesthproyecto

6.4. Arquitectura del Modelo 150

GetAllRoomsAction Con esta accion se permite recuperar una lista de las ha-

bitaciones. Para esto la accion necesita que se le pase desde donde necesita la

lista y la cantidad de habitaciones que se desean ver.

La accion simplemente recupera todos las habitaciones y las devuelve a traves

de un objeto HabitacionesCollectionChunkVO, para que luego pueda realizarse

una paginacion del resultado.

GetRoomAction Esta accion se encarga de recuperar los datos de una habitacion.

Para ello hay que pasarle el numero de la habitacion de la que se quieren

los datos. La accion recupera los datos mediante los DAOs pertinentes y los

devuelve.

GetRoomCompleteAction Esta accion se encarga de recuperar los datos de una

habitacion, las incidencias y los datos del tipo de habitacion. Para ello hay que

pasarle el numero de la habitacion de la que se quieren los datos.

La accion recupera los toda la informacion requerida mediante los DAOs que

correspondan y lo devuelve todo encapsulado en un Costum Value Object.

GetRoomsOfTypeAction Esta accion se encarga de recuperar todas las habita-

ciones que pertenecen a un tipo de habitacion. Para ello se le pasa el identifi-

cador del tipo de habitacion.

La accion recupera todas las habitaciones del tipo de habitacion indicado y las

devuelve todas juntas utilizando un objeto Collection.

6.4.4.4. Gestion de Ofertas

En esta seccion se mostrara como es el desarrollo de los casos de uso Gestion de Ofertas.

Como en los subsistemas anteriores se utilizan los patrones Session Facade y Business

Delegate para desarrollarlo

De aquı en adelante se mostrara como se organizan las clases que forman este subsistema

y luego se aclarara el cometido que tiene cada una de ellas. El subsistema se divide en dos

Page 183: Xesthproyecto

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 como se organizan las clases de la Session

Facade que gestiona los tipos de oferta, y en las figuras 6.41 y 6.42 se muestra unos

diagramas sencillos de la Gestion de Ofertas.

<<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

GeneralTipoOfertaFacade

<<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

-dataSource : DataSource

<<realize>>

actions

Figura 6.39: Diagrama Simple de Gestion de Tipos de Ofertas

Page 184: Xesthproyecto

6.4. Arquitectura del Modelo 152

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>NonTransactionalPlainAction

<<interface>>TransactionalPlainAction

BorrarIncompatibleConAction

<<create>> +BorrarIncompatibleConAction(incompatibleConVO : IncompatibleConVO)+execute(connection : Connection) : Object

BorrarTipoOfertaAction

<<create>> +BorrarTipoOfertaAction(idTipoOferta : Long)+execute(connection : Connection) : Object

CambiarTipoOfertaAction

<<create>> +CambiarTipoOfertaAction(tipoOfertaVO : TipoOfertaVO)+execute(connection : Connection) : Object

CambiarTipoOfertaCompletaAction

<<create>> +CambiarTipoOfertaCompletaAction(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection)-isPetitionCongruent() : boolean+execute(connection : Connection) : Object

CrearIncompatibleConAction

<<create>> +CrearIncompatibleConAction(incompatibleConVO : IncompatibleConVO)+execute(connection : Connection) : Object

CrearTipoOfertaAction

<<create>> +CrearTipoOfertaAction(tipoOfertaVO : TipoOfertaVO)+execute(connection : Connection) : Object

CrearTipoOfertaCompletaAction

<<create>> +CrearTipoOfertaCompletaAction(tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Collection,colIncompatibleConVO : Collection)-isPetitionCongruent() : boolean+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

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 Gestion de Tipos de Ofertas

Page 185: Xesthproyecto

6.4. Arquitectura del Modelo 153

Este Session Facade es el encargado de manejar la creacion, recuperacion y consulta

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 metodos de la fachada delegan su funcionamiento en las acciones

del subpaquete Actions que se explicaran a continuacion.

Las acciones en base a las cual se implementan las operaciones de TipoOfertasFacade,

se podran clasificar como transaccionales y no transaccionales. Ademas, a diferencia de

otros Session Facade, estas acciones son algo mas complejas, debido a que hay que tener

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 accion se encarga de crear un nuevo tipo de oferta.

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 accion sera la encargada de crear una in-

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 incompa-

tibilidad es recıproca, es decir, si A es incompatible con B entonces B tambien

es incompatible con A.

A continuacion se comprueba que la incompatibilidad no existe, en ese caso se

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 que sera aplicable, en el mismo momento.

Esta accion da soporte para que eso se pueda realizar. Como se puede adivinar,

en este caso se necesitaran los datos del tipo de oferta, pero ademas tambien

Page 186: Xesthproyecto

6.4. Arquitectura del Modelo 154

se necesitara un conjunto de todas las incompatibilidades que se deseen crear,

y otro que contenga todos aquellos productos a los que se podra aplicar el tipo

de oferta.

Primero se comprueba que todos los datos recibidos sean congruentes, por ejem-

plo, 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 anaden las incompatibilidades y los productos a

los que se aplicara (siempre y cuando no esten ya en la base de datos), sino se

crea el nuevo tipo y todas sus relaciones.

CambiarTipoOfertaAction Esta accion permite modificar los datos de un tipo

de oferta. Para eso le hay que pasar los nuevos datos del tipo de oferta.

La accion, comprueba que el tipo de oferta exista, de ser ası recupera la infor-

macion antigua, la compara con los nuevos datos y actualiza aquellos que se

han cambiado.

CambiarTipoOfertaCompletaAction Al igual que CambiarTipoOfertaAction,

permite cambiar los datos de un tipo de oferta, pero en este caso tambien se

permitira cambiar las incompatibilidades y los productos a los que es aplicable

el tipo de oferta.

Del mismo modo que CrearTipoOfertaCompletaAction, esta accion recibe los

mismos parametros y comprueba que la peticion sea congruente, luego recupera

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 accion encargada de eliminar una incom-

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.

Page 187: Xesthproyecto

6.4. Arquitectura del Modelo 155

La accion busca la incompatibilidad en ambos sentidos, A con B y B con A, y

si las encuentra las elimina.

BorrarTipoOfertaAction Se encarga de borrar un tipo de oferta. Para realizar

esta operacion la accion simplemente necesita el identificador del tipo de oferta,

lo busca en la base de datos y todas sus incompatibilidades. Una vez que ha

recuperado todos los datos entonces los elimina.

ExistsIncompatibleConAction Esta accion es la encargada de chequear si existe

una incompatibilidad entre dos tipos de oferta. Para hacer esta comprobacion

necesita que se le pase un objeto VO con los dos identificadores que se desean

buscar. Devuelve el resultado a traves de un objeto ’boolean’.

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 accion busca los datos solicitados y devuelve un objeto ’Collection’ con la

informacion requerida.

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 accion busca los tipos de oferta que son incompatibles con el indicado y

devuelve un objeto ’Collection’ con la informacion requerida.

RecuperarTipoOfertaAction Con esta accion se permite recuperar los datos de

un tipo de oferta. Para ello se le especifica el identificador del tipo.

La accion simplemente recupera los datos del tipo de oferta solicitado y los

devuelve a mediante un objeto TipoOfertaVO.

RecuperarTipoOfertasAction Esta accion se encarga de recuperar todos los ti-

pos de oferta, desde una posicion determinada y la cantidad que se solicite.

Page 188: Xesthproyecto

6.4. Arquitectura del Modelo 156

Para ello se le indica la posicion desde la que se desea comenzar a recuperar y

la cantidad de tipos que se quieren.

La accion recupera todos los tipos requeridos y los devuelve en un objeto ’Co-

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

GeneralOfertaFacade

<<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

-dataSource : DataSource

<<realize>>

actions vo

<<interface>>OfertaCompletaChunkVO GeneralOfertaCompletaChunkVO

<<realize>>

OfertasCollectionChunkVO

Figura 6.41: Diagrama Simple de Gestion de Ofertas

Page 189: Xesthproyecto

6.4. Arquitectura del Modelo 157

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>NonTransactionalPlainAction

<<interface>>TransactionalPlainAction

CrearOfertaAction

<<create>> +CrearOfertaAction(ofertaVO : OfertaVO)+execute(connection : Connection) : Object

CrearOfertaCompletaAction

<<create>> +CrearOfertaCompletaAction(ofertaVO : OfertaVO,tipoOfertaVO : TipoOfertaVO,colAplicableAVO : Map,colIncompatibleConVO : Collection)-isPetitionCongruent() : boolean-createNecesaryCollections(id : Long) : void+execute(connection : Connection) : Object

CambiarOfertaAction

<<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

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

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 Gestion de Ofertas

Page 190: Xesthproyecto

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 metodos

de la fachada delegan su funcionamiento en las acciones del subpaquete Actions que se

explicaran a continuacion.

Para implementar algunas de las acciones de esta fachada hubo que realizar un siste-

ma aparte que se puede ver a grandes rasgos en la figura 6.49 de la seccion 6.4.5. Este

sistema sera el encargado de realizar las operaciones relativas al calculo de descuentos

proporcionados por las ofertas que actualmente estan en vigor. En la seccion 6.4.5 se ex-

plicara en detalle el funcionamiento de este sistema, sus principales tareas, y como estan

implementadas.

Esta fachada tambien manejara unos objetos especiales, los Custom Value Objects. Este

tipo de objetos, cuyo uso y cometido ya se ha mencionado en la explicacion de subsistemas

anteriores, se encontraran en el subpaquete ’vo’. Cabe destacar el OfertaCompletaChunk-

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 demas datos

que se encapsulan. Luego proporciona metodos de lectura y escritura como cualquier Value

Object.

Las acciones en base a las cual se implementan las operaciones de HabitacionesFacade,

se podran clasificar como transaccionales y no transaccionales como ocurrıa en los demas

subsistemas. Estas acciones son las que se comentan a continuacion:

CrearOfertaAction Esta accion se encarga de crear una nueva oferta. Para ello se

le pasan los datos de la nueva oferta y utilizando los DAOs pertinentes inserta

su informacion en la base de datos.

CrearOfertaCompletaAction Al igual que la accion anterior, se encarga de crear

una nueva oferta, pero en algunas ocasiones sera necesario crear la oferta y el

Page 191: Xesthproyecto

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 informacion del nuevo tipo de oferta, los tipos

con los cuales este es incompatible y los productos a los cuales se podra aplicar.

Primero se comprueba que los datos sean congruentes, del mismo modo que se

hacıa en CrearTipoOfertaCompletaAction. Luego se insertan todos los datos

nuevos en la base de datos, en el caso de que algun dato ya exista simplemente

se actualiza su informacion.

CambiarOfertaAction Esta accion es la encargada de modificar los datos de una

oferta. Para ellos se le pasan los nuevos datos de la oferta.

A continuacion se buscan los datos antiguos de la oferta y se comparan con la

nueva informacion proporcionada, en los casos en que no coincidan se actualizan

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 correspon-

dientes se elimina de la base de datos

PublicarOfertaAction Se encarga de publicar o dar de baja una oferta. El me-

canismo de dar de baja se proporciona por si en algun momento se publica

una oferta que va en contra de los intereses del negocio. A esta accion hay que

pasarle el identificador de la oferta y un objeto de tipo ’boolean’ indicando si

se desea publicar o no la oferta.

A traves de los DAO necesarios esta accion actualiza esta informacion en la

base de datos.

CalcularDescuentoAction Es la encargada de, a partir de un conjunto de pro-

ductos, calcular el mejor descuento que puedan proporcionar las ofertas que se

puedan aplicar a esos productos.

Page 192: Xesthproyecto

6.4. Arquitectura del Modelo 160

Para dar soporte a esta accion y al proceso que debe realizar se define una

interfaz que deben implementar todos aquellos productos a los que se les pueda

hacer algun tipo de descuento. Esta interfaz es la interfaz Ofertable, se puede

ver en la figura 6.43 y otra que a partir de un conjunto de objetos Ofertable los

divide en subconjuntos segun el tipo de producto que definan, esta es la interfaz

OfertableCollectionChunkVO tambien presente en la figura 6.43

<<interface>>Ofertable

+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

<<interface>>OfertableCollectionChunkVO

+getDescuento() : double+setDescuento(descuento : double) : void+getTipoOfertable() : String+getCantidad() : double+extractOfertableCollection() : Collection+acumulateDiscount(discount : Double) : void

GeneralOfertableCollectionChunkVO

<<create>> +GeneralOfertableCollectionChunkVO(c : Collection,muestra : Ofertable)+getDescuento() : double+getTipoOfertable() : String+setDescuento(descuento : double) : void+getCantidad() : double+extractOfertableCollection() : Collection+acumulateDiscount(discount : Double) : void

-collectionDeT : Collection-tipoOfertable : String-descuento : double-cantidad : double

<<realize>>

0..* 1

Figura 6.43: Diagrama de la Interfaz Ofertable

Esta accion necesita recibir el DNI o Pasaporte del cliente para el que se destina

el calculo del descuento, y un conjunto de objetos Ofertable que definan todos

los objetos sobre los cuales se haran los calculos para el descuento.

Una vez se tienen todos estos datos, se delega la operacion en el metodo ’Cal-

cularMejorPara’ del calculador de ofertas definido en el sistema de ofertas. El

funcionamiento de este sistema se muestra en detalle en la seccion 6.4.5

RecuperarOfertaAction Se encarga de recuperar los datos de una oferta. Se le

debe pasar el identificador de la oferta.

A continuacion la accion recupera los datos de la oferta solicitada y los devuelve,

en caso de que la oferta que se pida no exista se lanza una excepcion.

Page 193: Xesthproyecto

6.4. Arquitectura del Modelo 161

RecuperarOfertasAction Esta accion es la encargada de recuperar una lista de

todas las ofertas. Para llevar a cabo esta accion, necesita que le pasen desde

donde se quiere recuperar y la cantidad de ofertas que se desean.

Luego la accion, a traves de los DAO correspondientes, recoge las ofertas solici-

tadas y las devuelve encapsuladas en un Custom Value Object preparado para

realizar paginacion.

RecuperarOfertasActualesAction Con esta accion se permite recuperar una lis-

ta de las ofertas que se aplican actualmente. Para ello necesita que se le pase

desde donde se quieren recuperar las ofertas y la cantidad.

A continuacion la accion recupera los datos a traves de los DAOs y los encapsula

en un Custom Value Object, de esta forma, como ya se ha visto, se consigue

una paginacion de los resultados.

RecuperarOfertasBorradoresAction Esta accion permite recuperar una lista

de las ofertas que aun estan como borradores. Para ello necesita que se le pase

desde donde se quieren recuperar las ofertas y la cantidad.

A continuacion la accion recupera los datos a traves de los DAOs y los encapsula

en un Custom Value Object, para conseguir una paginacion de los resultados.

RecuperarOfertasPublicadasAction Permite recuperar una lista de las ofertas

que aun estan actualmente publicadas. Para ello necesita que se le pase desde

donde se quieren recuperar las ofertas y la cantidad.

A continuacion la accion recupera los datos a traves de los DAOs y los encapsula

en un Custom Value Object, para conseguir una paginacion de los resultados.

RecuperarOfertasPorTipoAction Esta accion se encarga de recuperar todas las

ofertas de un mismo tipo de oferta. Para realizarlo necesita que se le pase desde

donde se quieren recuperar las ofertas y la cantidad.

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.

Page 194: Xesthproyecto

6.4. Arquitectura del Modelo 162

6.4.4.5. Gestion de Facturas

En esta seccion se mostrara como es el desarrollo de los casos de uso de Gestion de

Facturas. Como en los casos anteriores se utiliza el patron Session Facade y Business

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; tambien

ofrecera una operacion para cancelar una reserva, calculando el recargo de tal operacion

si la factura ya estaba pagada.

De aquı en adelante se mostrara como se organizan las clases que forman este subsistema

y luego se aclarara el cometido que tiene cada una de ellas. En las figuras 6.44 y 6.45 se

muestra unos diagramas sencillos de la Gestion de Facturas.

<<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

GeneralFacturasFacade

<<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

-dataSource : DataSource

<<realize>>

actions exceptionsvo

FacturaCompletaChunkVO

Figura 6.44: Diagrama Simple de Gestion de Facturas

Page 195: Xesthproyecto

6.4. Arquitectura del Modelo 163

<<interface>>NonTransactionalPlainAction

<<interface>>PlainAction

+execute(connection : Connection) : Object

<<interface>>TransactionalPlainAction

CalcularBorradorFacturaAction

<<create>> +CalcularBorradorFacturaAction(idFactura : Long)+execute(connection : Connection) : Object

CancelarReservaAction

<<create>> +CancelarReservaAction(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

GetImporteADevolverCancelacionAction

<<create>> +GetImporteADevolverCancelacionAction(codReserva : Long)+execute(connection : Connection) : Object-calculaDevolucionDe(c : Connection,linea : LineaDeReservaVO) : double

PayBillAction

<<create>> +PayBillAction(codBill : Long)+execute(connection : Connection) : Object

PaymentConfirmationAction

<<create>> +PaymentConfirmationAction(codBill : Long)+execute(connection : Connection) : Object

SetBillAsPayedAction

<<create>> +SetBillAsPayedAction(codBill : Long)+execute(connection : Connection) : Object

Figura 6.45: Actions y Exceptions de Gestion de Facturas

En estos diagramas se puede ver como se vuelven a usar los patrones Session Facade

y Business Delegate. La interfaz para acceder a este subsistema es FacturasFacade, im-

plementado por GeneralFacturasFacade. Al igual que en el Session Facade anterior, los

metodos de la fachada delegan su funcionamiento en las acciones correspondientes del

subpaquete Actions. A continuacion se explicara el funcionamiento de cada una de las

acciones.

Ademas de usar unas acciones para implementar sus metodos, esta fachada tambien

lanza CustomException para proporcionar informacion a las capas superiores acerca del

estado con el que finalizo la operacion. En este caso se usaran excepciones para informar

si se ha podido realizar correctamente el pago de una factura y si se ha podido cancelar

una reserva.

Page 196: Xesthproyecto

6.4. Arquitectura del Modelo 164

Por otro lado, esta fachada manejara un objeto especiale, un Custom Value Object.

Estes objeto estara localizado en el subpaquete ’vo’ y tendran como cometido ofrecer a las

capas superiores un conjunto de los atributos de varios VO ya existentes. En este caso se

usara para encapsular una factura y todas sus lıneas de reserva.

Las acciones en base a las cuales se implementan las operaciones de FacturasFacade,

tambien podran clasificarse como transaccionales y no transaccionales dependiendo si es

necesario que la operacion se realice de forma atomica o no, y son las siguientes:

CalcularBorradorFacturaAction Esta accion es la encargada de calcular el im-

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 iden-

tificador de la factura que se desea procesar.

A continuacion la accion recupera todas las lıneas de reserva, y ayudandose de

las operaciones que proporciona el objeto OfertableCollectionChunkVO divide

el conjunto de lıneas recuperadas en varios segun el tipo de producto reservado

en cada lınea.

Luego utilizando el CalculadorDeOferta del Sistema de Ofertas (se comen-

tara en detalle en la seccion 6.4.5) calcula las mejores ofertas que se podran

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 accion permite cancelar una reserva. Para ello se le

debe pasar el codigo de la reserva que se quiere cancelar.

Luego se recuperan todas las lıneas de reserva de la reserva que se quiere can-

celar y se marcan como canceladas. A continuacion se actualizan los totales de

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.

Page 197: Xesthproyecto

6.4. Arquitectura del Modelo 165

A continuacion se marca la factura como que ya no es un borrador, si la factura

ya estaba pagada, en proceso de pago o cancelada, se lanza una excepcion

indicandolo.

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 accion, necesita que le pasen el identificador de la factura.

Luego se actualizan los datos de la factura indicando que ya esta pagada.

SetBillAsPayedAction Esta accion es la encargada marcar una factura como pa-

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 operacion.

La accion actualiza la informacion de la factura y marcandola como pagada y

que ya no es borrador.

GetImporteADevolverCancelacionAction Esta accion es la encargada de cal-

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 accion recupera todas las lıneas de reserva de esa reserva y segun los

dıas que resten para que la reserva se haga efectiva se devuelve un porcentaje

del importe u otro. Para finalizar se actualizan los datos de las lıneas de reserva

y la factura.

GetFacturaAction Esta accion es la encargada de recuperar los datos de una

factura. Para ello necesita el identificador de la factura que se desea.

A continuacion se recuperan los datos de la factura y las lıneas de reserva que

la componen y se devuelven encapsulados en un Custom Value Object.

GetFacturasEntreFechasAction Esta accion es la encargada de recuperar los

datos de todas las facturas pagadas entre dos fechas. Para ello necesitan: la

Page 198: Xesthproyecto

6.4. Arquitectura del Modelo 166

fecha mas temprana y la mas tardıa entre las cuales se desean recupera las

facturas.

A continuacion se recuperan los datos de las facturas mediante los DAO y

devuelven a traves de un objeto Collection.

6.4.5. Sistema de Soporte - Modelo de Ofertas

6.4.5.1. Requisitos del Sistema de Ofertas

El sistema de Ofertas es un sistema de soporte, totalmente independiente del resto de

la aplicacion. Este modelo proporcionara una serie de funcionalidades, todas ellas relacio-

nadas con las ofertas.

En el caso del software que se esta desarrollando, se pide que las ofertas cumplan unos

requisitos que no son triviales de implementar, por esa razon se concluyo que la mejor

solucion serıa desarrollar un sistema que funcionara de manera independiente. De esta

forma, si en el futuro se desea cambiar el comportamiento de las ofertas en el negocio para

el que se destina la aplicacion, unicamente habrıa que modificar este sistema. Antes de

detallar como se diseno el sistema, se explicara brevemente los requisitos que este tiene

que cumplir, y como se deben organizar las diferentes ofertas unas con otras.

Todas las ofertas estaran asociadas a un tipo de oferta, este tipo es el primero que se

va a definir. Cada tipo de oferta especifica entre otras cosas a que tipo de productos del

negocio esta destinado y cual es la cantidad mınima necesaria de esos productos para

que una oferta de este tipo se pueda aplicar. Ademas, como las ofertas deben poder ser

acumulables, hay que definir unas incompatibilidades de unos tipos de oferta con otros,

de esta forma solo se podran aplicar conjuntamente aquellas ofertas que sean de tipos

compatibles todos entre sı, este es uno de los problemas a los que habra que hacer frente

en el diseno de este sistema.

Page 199: Xesthproyecto

6.4. Arquitectura del Modelo 167

Por otro lado, todas las ofertas de un mismo tipo seran incompatibles por definicion, y

cada oferta tiene que poder definir una regla, mediante la cual, en un contexto determinado

(cliente, reserva, fecha, etc) se pueda decidir automaticamente si la oferta se puede aplicar

en una factura o no. La definicion del lenguaje de reglas necesario para dar solucion a esta

necesidad es el segundo de los problemas que debe resolverse con este sistema.

Solucion al Problema de las Incompatibilidades

Como todas las ofertas de un mismo tipo son incompatibles, para elegir la mejor de

todas simplemente se eligira la que proporcione un mayor descuento de entre las que

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

demas de los otros tipos, siempre y cuando los tipos de oferta no sean incompatibles.

Para resolver la incompatibilidad entre los distintos tipos, se ideo constuir un grafo

de incompatibilidades donde los nodos representan los tipos y los arcos indican que

dos tipos son incompatibles.

Para poner un ejemplo de como se resuelve este problema mediante un grafo, se

tomaran 5 tipos de oferta, A, B, C, D y E. El tipo de oferta E sera incompatible con

el A, el B y el C; y el tipo B con el C. Ası se muestra en el siguiente grafo.

A B C

D E

Grafo ’g’ - Ejemplo de Incompatibilidades

Page 200: Xesthproyecto

6.4. Arquitectura del Modelo 168

Una vez observado el grafo en el que se expresan las incompatibilidades hay que darle

solucion, y conseguir deducir todos aquellos conjuntos de ofertas que son compatibles

entre sı.

Como un estudio puramente matematico llevarıa mucho tiempo, se buscara una

forma practica de resolverlo. Para ello se intentara buscar una serie de pasos con los

cuales se puedan ir obteniendo aproximaciones de la solucion que se busca.

Una primera aproximacion podrıa ser, dado que se tiene un grafo de incompatibili-

dades, crear el grafo de compatibilidades correspondiente. Pero esto tendrıa un serio

coste computacional si aumentasen las ofertas (nodos) del grafo. Teniendo esto en

cuenta, y utilizando algo de notacion matematica, se puede calcular una matriz de

adyacencia del grafo de incompatibilidades identificando la presencia de una relacion

de incompatibilidad mediante un ’1’ y la ausencia de la misma con un ’0’, de esta

forma se puede ver muy facilmente y de manera compacta con que otras ofertas

es compatible una dada, simplemente identificando los ’0’ de una fila de la matriz.

Los nombres que se daran a las filas y columnas de la matriz de adyacencia seran:

’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:

Ady(g) =

0 0 0 0 1

0 0 1 0 1

0 1 0 0 1

0 0 0 0 0

1 1 1 0 0

De la matriz Ady(g) se puede sacar facilmente el grafo de compatibilidades, ya que

en ese caso las relaciones de compatibilidad serıan las representadas por los ’0’. Con

esta simple matriz ya se puede saber que ofertas son compatibles y con cuales, pero

aun falta algo, se ve claramente con el siguiente ejemplo: con los datos de la matriz se

Page 201: Xesthproyecto

6.4. Arquitectura del Modelo 169

llega a la conclusion de que ’A’ es compatible con ’A’, ’B’, ’C’ y ’D’, pero lo que no se

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ıan aplicar conjuntamente.

¿Como solucionarlo?, lo que se necesita es calcular conjuntos de ofertas que sı sean

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’ logicos de cada una de las filas

con las filas de cada uno de sus componentes con los que es compatible, o como se

vera a continuacion, utilizando conjuntos y haciendo intersecciones de los conjuntos

compatibles, dando como resultado un conjunto de ofertas todas compatibles entre

sı.

Se puede observar mucho mas facilmente resolviendo el ejemplo con el que se esta tra-

bajando. Primero se realiza el calculo de Ady(g), la matriz complementaria a Ady(g).

Ady(g) =

1 1 1 1 0

1 1 0 1 0

1 0 1 1 0

1 1 1 1 1

0 0 0 1 1

A partir de la informacion de esta matriz, se comienza identificando el conjunto de

ofertas que son compatibles con ’A’, las que lo son con ’B’, etc. Estos conjuntos se

identificaran como C(A), C(B), C(C), C(D) y C(E), y a los conjuntos resultantes de

ofertas compatibles entre sı se les llamara R(A), R(B), R(C), R(D) y R(E). En el

ejemplo con el que se esta trabajando se tienen los siquientes conjuntos:

C(A) = {A,B,C,D}

C(B) = {A,B,D}

C(C) = {A,C,D}

Page 202: Xesthproyecto

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

interseccion de cada uno de los conjuntos con los conjuntos de las ofertas con las que

es compatible. A continuacion se muestran estas intersecciones y los resultados:

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ıa aplicar sus descuentos conjuntamente en una factura. Una vez

resuelto este problema, el sistema debera escoger el conjunto que ofrece un mayor

descuento sobre el importe de la factura, esta operacion se realiza calculando el

descuento que ofrece cada uno de los conjuntos y escogiendo el que ofrezca el mayor

de todos.

Solucion al Problema de las Reglas para las Ofertas

Como ya se ha mencionado, el sistema debe proporcionar la mayor flexibilidad po-

sible para que las ofertas definan su ambito de aplicacion. Para realizarlo se debe

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 hara falta guardar la regla junto con los datos de la oferta en la base

de datos, esta se almacenara de forma textual.

Page 203: Xesthproyecto

6.4. Arquitectura del Modelo 171

Una regla sera una cadena de caracteres, entre los cuales se intercalaran caracteres

especiales para indicar las diferentes partes y funcionalidades que tendran las demas

subcadenas. Esto es lo primero que hay que hacer, definir una sintaxis que se utili-

zara en la construccion de las distintas reglas. Ademas, para que una regla se pueda

adaptar facilmente a la situacion en la que se va a aplicar, se tienen que proporcio-

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 medicion distintas. En otras

palabras, con una regla se tendran que poder definir cosas como: la fecha a partir de

la cual habrıa que hacer una reserva para que se aplique la oferta, la edad mınima

del cliente, la edad maxima, el paıs de origen, etc. Y poder proporcionar en el futuro

formas de definir otros aspectos contra los cuales se pueda cotejar la aplicacion de

una oferta.

Para dar cabida a definir todos estos aspectos y posibilitar la definicion de mas,

se ve necesario que una regla se divida en partes bien diferenciadas donde cada

parte definira una unica situacion y para que una regla se cumpla, se deben cumplir

todas las partes. Cada una de las partes tendra un identificador (nombre) y unos

parametros que necesitara para chequearse, por ejemplo, a la parte de regla que debe

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 utilizaran para separar las diferentes partes de la regla seran

’&&’. Luego hara falta diferenciar el identificador de cada parte de sus parametros,

para eso se utilizara ’:’ y dentro de la zona de los argumentos hay que diferenciar

cada uno de ellos, para lo que se hara uso del caracter ’,’. Un ejemplo de como que-

darıa una regla es el siguiente:

PersonBornBefore:30,8,1987&&PersonFrom:Espana

Page 204: Xesthproyecto

6.4. Arquitectura del Modelo 172

El ejemplo de regla anterior permitirıa que la oferta se aplicase si el cliente al que

va destinada nacio antes del 30 de Agosto de 1987 y solo si tiene su domicilio en

Espana. Podrıa suceder tambien que hubiese una parte de la regla sin argumentos o

que la regla no tubiese ninguna parte.

6.4.5.2. Diseno e Implementacion del Sistema de Ofertas

A diferencia de como se han explicado los subsistemas anteriores, en este caso se comen-

zara describiendo las funcionalidades que ofrecen las clases mas importantes del sistema.

Se recorrera este modelo dividiendolo en subconjuntos de clases que proporcionen funcio-

nalidades necesarias para el resto de la aplicacion.

En primer lugar se describiran las clases necesarias para dar soporte al sistema de

las reglas para las ofertas y como se relacionan entre sı. La mejor forma de ver como

interactuan diferentes clases es a traves de un diagrama, ası lo podremos observar en la

figura 6.46.

Page 205: Xesthproyecto

6.4. Arquitectura del Modelo 173

RulePartFactory

+getValidRuleParts() : Collection+getRulePart(key : String,args : String[]) : RulePart+getRulePart(key : String) : RulePart+existsRulePart(key : String) : boolean

-availableRuleParts : Collection-availableRulePartsFile : String

Rule

<<create>> +Rule(s : String)-getKey(s : String) : String-getArgs(s : String) : String[]+isOfferApplicable(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isRuleCorrectlyFormed(s : String) : boolean

-ruleParts : Collection

<<interface>>RulePart

+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

<<call>>

0..*

1

PersonBornAfter

<<create>> +PersonBornAfter()+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

-day : Integer-month : Integer-year : Integer

AlwaysTrue

<<create>> +AlwaysTrue()+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

PersonBornBefore

<<create>> +PersonBornBefore()+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

-day : Integer-month : Integer-year : Integer

PersonFrom

<<create>> +PersonFrom()+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

-country : String

ReservationDoneBefore

<<create>> +ReservationDoneBefore()+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

-day : Integer-month : Integer-year : Integer

Figura 6.46: Diagrama del Sistema de Reglas

Page 206: Xesthproyecto

6.4. Arquitectura del Modelo 174

La clase regla es la encargada de crear dinamicamente una regla y ofrece metodos de

comprobacion para saber si su aplicacion a un conjunto de productos ofertables, una

persona, etc, resulto exitosa o no, y de chequeo para saber si la cadena y todas sus partes

estan bien formadas. En realidad la regla no realiza estas comprobaciones, sino que delega

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 ayudandose de la clase RulePartFactory, la

cual se encarga de, a partir de un nombre identificativo crear un objeto RulePart. Para

saber que tipo de objeto implementa cada uno de los RuleParts solicitados, hace uso de la

clase de utilidad ConfigurationParametersManager. En el capıtulo 7, en el apartado 7.3.0.1

se podra observar como se realizo la implementacion de los metodos mas importantes de

esta clase.

Actualmente se proporcionan definidos en el sistema cinco tipos distintos de objetos

RulePart, pero anadir nuevas partes para las reglas serıa tan sencillo como crear un nuevo

objeto que implemente la interfaz RulePart y especificar su nombre y nombre de clase en

un fichero para que este localizable; a partir de ese momento ya se puede utilizar en la

aplicacion sin ningun problema.

Los tipos definidos son los siguientes:

AlwaysTrue Esta parte de regla no necesita de ningun parametro, cuando se utiliza

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ıa esta parte de regla.

PersonBornAfter En este caso, esta parte de regla necesita tres argumentos para

indicarle una fecha (dıa, mes y ano). En un primer lugar se comprueba que

la fecha este correctamente formada, y cuando se pide que se compruebe si se

cumple, lo que hace esta parte de regla es chequear si el cliente del contexto

Page 207: Xesthproyecto

6.4. Arquitectura del Modelo 175

actual tiene como fecha de nacimiento una posterior a la indicada mediante los

parametros.

PersonBornBefore Esta parte de regla necesita tres argumentos igual que la an-

terior para indicarle una fecha (dıa, mes y ano). Realiza las mismas comproba-

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 como

se debe crear un nuevo objeto RulePart.

PersonFrom En este caso se necesita un unico argumento para indicar el nombre

de un paıs. Primero se comprueba que se le pasa este argumento y luego debe

chequear que el cliente contra el que se debe validar la regla sea del paıs indicado.

ReservationDoneBefore Esta parte de regla se encarga de comprobar que la re-

serva se haga antes de una fecha, para ello necesita tres parametros para indicar

la fecha lımite que se desea establecer, luego se comprueba que la fecha sea co-

rrecta y que la reserva se este haciendo en realidad antes del dıa especificado.

Para dar implementacion a una nueva parte de regla lo unico que hay que hacer es

definir el comportamiento necesario de los metodos indicados en la interfaz RulePart.

En el capıtulo 7 en la seccion 7.3.0.3 se muestra la implementacion de la parte de regla

’PersonBornBefore’, cualquier otra implementacion de otra parte de regla que se quisiese

realizar serıa analoga a esa.

Una vez creada la nueva parte de regla hay que anadir una nueva entrada en el fichero de

configuracion ConfigurationParameters.properties para indicar donde se puede localizar la

nueva clase.

Ademas de las reglas, el sistema de ofertas necesitaba calcular el mejor conjunto de

ofertas compatibles que se podıan aplicar a los productos de una factura. En la seccion

anterior se desarrollo un algoritmo practico para dar solucion a este problema, este algo-

ritmo lo implementa una clase particular en el sistema, esta es, BestSetOfOffers, la cual, a

Page 208: Xesthproyecto

6.4. Arquitectura del Modelo 176

partir de los nodos del grafo (las ofertas) y los descuentos que estas proporcionan sobre la

coleccion de productos ofertables, calcula cual es el mejor conjunto de ofertas compatibles

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 solo resta comprobar cuanto es el

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 sera el buscado.

BestSetOfOffers

<<create>> +BestSetOfOffers(nodes : Map)+getBestSetOfOffersIds() : ArrayList+getBestDiscount() : Double-getAllIncompatibleWith() : void

-nodes : Map-relations : Collection-bestSetOfOffersIds : ArrayList-bestDiscount : Double

Figura 6.47: Diagrama de clase BestSetOfOffers

Page 209: Xesthproyecto

6.4. Arquitectura del Modelo 177

Para las expecativas que habıa sobre esta solucion, decir que, finalmente, es lo suficiente-

mente rapida y eficaz para satisfacerlas. Aun ası, si lo que se quiere es rapidez a la hora de

realizar calculos, se debe intentar que el calculo del conjunto de mejores ofertas se haga el

mınimo numero de veces posible. Como esta operacion solo serıa estrictamente necesaria

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 aplicacion final.

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 mostrara la clase que funciona como

interfaz para las capas superiores, abstrayendo todo el funcionamiento que se ha explicado.

Esta clase es ‘CalculadorImpl‘ que implementa la interfaz ‘Calculador‘. La clase Calcula-

dorImpl es la encargada de realizar el calculo del mejor conjunto de ofertas aplicables a un

conjunto de productos ‘Ofertable‘, haciendo uso de ‘BestSetOfOffers‘ para dicho calculo.

En un nivel superior se encuentra la clase ‘GeneralCalculadorDeOferta‘ que es el encar-

gado 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 decision de si

una oferta se puede aplicar o no, del calculo del mejor conjunto de ofertas. Se utiliza para

esto el proceso denominado ‘delegacion‘ a traves del cual, GeneralCalculadorDeOferta rea-

liza las operaciones que le corresponden y delega en CalculadorImpl el calculo del mejor

conjunto de ofertas. De este modo, el dıa de manana se podrıa cambiar, si se quisiese, la

implementacion de ‘Calculador‘ para que sea mas eficiente.

A continuacion se muestran los metodos que ofrecen estas dos clases en la figura 6.48

Page 210: Xesthproyecto

6.4. Arquitectura del Modelo 178

<<interface>>CalculadorDeOferta

+CalcularMejorPara(c : Connection,colOfertable : Collection,dniPasPersona : String) : Collection+setCalculador(c : Calculador) : void+getAppliedOffers() : Collection

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

-colDeCol : Collection-calculador : Calculador-colOfApplied : Collection

<<interface>>Calculador

+calculaMejorOferta(colProductos : Collection,colOfertasPosibles : Collection) : Collection+getAppliedOffers() : Collection

1

1

CalculadorImpl

+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

-myProxyMap : Map-myBestSetOfOffersTypes : Collection-myFinalOfertableCol : Collection

Figura 6.48: Diagrama de las Clases Calculadoras

Page 211: Xesthproyecto

6.4. Arquitectura del Modelo 179

De la clase GeneralCalculadorDeOferta se podrıa destacar el metodo ‘calcularMejorPara‘

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 segun el tipo de Ofertable, a continuacion se recuperan todas las

ofertas y ayudandose del sistema de reglas, se escogen simplemente aquellas que segun su

regla se puedan aplicar. Una vez que se tienen estos datos, se delega el resto del calculo

en el metodo ‘calculaMejorOferta‘ del objeto ‘Calculador‘.

Otro metodo importante es ‘calculaMejorOferta‘ de la clase CalculadorImpl, encargado

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 podra aplicar una oferta. A continuacion se calcula el descuento que

proporciona cada una de las ofertas elegidas, y se le pasa esta informacion a BestSetOfOf-

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 seccion 7.3.0.2 se muestra la implementacion final de estos dos

metodos.

Una vez visto el funcionamiento de todas las clases de este sistema de soporte por se-

parado, se muestra como se relacionan entre sı todas ellas de forma compleja, de forma

que si el dıa de manana hubiese que cambiar algun componente, el proceso fuese practi-

camente de “Enchufar y Listo”. Se muestra a continuacion un diagrama de clases de esta

organizacion en la figura 6.49 donde se puede observar de forma simplificada la relacion

entre las clases.

Del mismo modo, tambien se puede observar como unas clases delegan parte de su

funcionamiento en otras, a traves del diagrama de secuencia de alto nivel que se muestra

en la figura 6.50. En ella se ve claramente el proceso de delegacion, gracias al cual, una de

las clases no se tiene que preocupar de realizar toda la operacion, sino que se realiza una

Page 212: Xesthproyecto

6.4. Arquitectura del Modelo 180

parte y deja que otra clase se encargue de uno de los trozos. Se podrıa tambien considerar

esto como una aplicacion de “Divide y Venceras”, done en cada metodo solo se trata una

parte de la funcionalidad a implementar, simplificando en gran medida la codificacion de

los metodos de las diferentes clases debido a que las operaciones que se realizan en cada

uno de ellos son mucho mas sencillas que si se realizara todo junto.

Page 213: Xesthproyecto

6.4.A

rquitectu

radel

Modelo

181

<<interface>>CalculadorDeOferta

+CalcularMejorPara(c : Connection,colOfertable : Collection,dniPasPersona : String) : Collection+setCalculador(c : Calculador) : void+getAppliedOffers() : Collection

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()

<<interface>>Calculador

+calculaMejorOferta(colProductos : Collection,colOfertasPosibles : Collection) : Collection+getAppliedOffers() : Collection

1

1<<call>>

CalculadorImpl

+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

BestSetOfOffers

<<create>> +BestSetOfOffers(nodes : Map)+getBestSetOfOffersIds() : ArrayList+getBestDiscount() : Double-getAllIncompatibleWith() : void

<<call>>

RulePartFactory

+getValidRuleParts() : Collection+getRulePart(key : String,args : String[]) : RulePart+getRulePart(key : String) : RulePart+existsRulePart(key : String) : boolean

Rule

<<create>> +Rule(s : String)-getKey(s : String) : String-getArgs(s : String) : String[]+isOfferApplicable(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isRuleCorrectlyFormed(s : String) : boolean

<<create>>

<<call>>

<<call>>

<<interface>>RulePart

+setArgs(args : String[]) : void+isRulePartApplicableTo(of : OfertaVO,colDeCol : Collection,dniPas : String) : boolean+isCorrect(args : String[]) : boolean

0..*

1<<instantiate>>

Figura 6.49: Diagrama Simple del Sistema de Ofertas

Page 214: Xesthproyecto

6.4.

Arq

uitec

tura

del

Model

o18

2

Figura 6.50: Diagrama Secuencia de la Accion de Calcular

Page 215: Xesthproyecto

Capıtulo 7

Implementacion

7.1. Detalles Especıficos de la Implementacion

A continuacion seran especificados ciertos problemas que surgieron y detalles que se

tuvieron en cuenta a la hora de implementar el sistema.

El primer y principal problema surgido en la implementacion fue utilizando el maneja-

dor JDBC para MySQL en su version mas reciente, debido a que a la hora de conectarse

con la base de datos lanzaba excepciones el driver diciendo que era imposible realizar la

conexion, despues de contactar con comunidades de usuarios de MySQL y no encontrar

solucion, habiendo tambien otros desarrolladores con el mismo problema, se decide inten-

tar solventar el problema analizando en profundidad la traza de la exepcion. Esta idea fue

la acertada, ya que a traves de este analisis se concluye que el error era provocado por la

codificacion de caracteres utilizada por defecto por la conexion. A partir de esta informa-

cion y documentandose sobre las opciones que se pueden pasar al driver de MySQL en el

momento del establecimiento de conexion se consiguio resolver el problema, publicandolo

en las comunidades de MySQL1 y recibiendo agradecimientos de los usuarios que tenıan

ese mismo problemas.

1La comunidad en la que se publico la solucion de este problema fue en: http://forums.mysql.com/exactamente en el siguiente hilo: http://forums.mysql.com/read.php?39,259743,259939#msg-259939

183

Page 216: Xesthproyecto

7.1. Detalles Especıficos de la Implementacion 184

Para la escritura del codigo fuente de la aplicacion se siguieron las normas que se es-

tablecen en las Convenciones de Codigo Java (Java Code Conventions). De este modo

sera mucho mas facil de entender el codigo fuente de la aplicacion para futuros desarrolla-

dores que realicen el mantenimiento de esta.

Lo primero que se hizo fue decidir que objetos se utilizarıan para manejar las fechas

y los conjuntos de objetos del mismo tipo. Para el manejo de fechas se empleo la clase

Calendar, ya que ofrece grandes ventajas a la hora de consultar una fecha y porque ya

esta practicamente integrada en las tecnologıas utilizadas. Por otro lado para gestionar

conjuntos de elementos se utilizo el objeto Collection, ya que este permite realizar bucles

utilizando un objeto Iterator, lo que hace algo mas comodo el trabajo del programador.

Ademas de la eleccion de los objetos pertinentes para realizar la implementacion, tam-

bien se introdujeron unas clases xxxManager en la capa controlador de la aplicacion, estas

clases tienen dos funciones fundamentales, la primera, realizar de cache, para evitar rea-

lizar multiples veces la misma consulta al modelo, y la segunda, sirve para amortiguar el

acceso al modelo en cuanto al numero de operaciones invocadas se refiere. Un ejemplo de

esto es la clase ReservationsManager que permite anadir nuevas lıneas de reserva a una

reserva o incluso modificarla eliminando lıneas, sin realizar esta operacion directamente

contra el modelo, sino que realiza los cambios internamente en su cache y luego en el mo-

mento de guardar hace los cambios todos juntos. Esto tambien posibilita que si el usuario

desea cancelar un proceso de modificacion, por ejemplo, los cambios que haya realizado

no haya que deshacerlos invocando a operaciones del modelo.

Para la implementacion del cambio de idioma de la interfaz web se consideraron dos

opciones, la opcion logica, serıa que en cualquier momento el usuario pudiese cambiar el

idioma de la aplicacion y que inmediatamente le cambiase el idioma de donde esta actual-

mente este usuario, pero esta no se pudo adoptar. Esta opcion no se pudo implementar,

debido a que la unica forma de que se cargara el nuevo idioma serıa cargar de nuevo la

pagina y si el usuario se encuentra en algun paso de un formulario se le enviarıa automati-

camente una peticion identica a la ultima operacion que realizo. A raız de este compor-

Page 217: Xesthproyecto

7.2. Implementacion de las Base de Datos 185

tamiento no desado se decidio que, siempre que el usuario decidiese cambiar de idioma la

aplicacion, fuese redireccionado a la pagina principal. De esta forma se consiguen evitar

comportamientos erroneos o inconsistentes

7.2. Implementacion de la Base de Datos

Aunque realmente las dos bases de datos que se utilizaran se podrıa separar en dos bases

de datos distintas, por motivos de simplicidad se considero que las tablas se creasen en

la misma base de datos. La base de datos se creo en localhost con el nombre bd hotel. A

continuacion se mostraran el proceso de creacion de las diferentes tablas y la insercion de

los dos usuarios por defecto del sistema ’admin’ y ’receptionist’, a traves de unas consultas

SQL.

7.2.1. Implementacion de la Base de Datos General

A partir del diseno explicado en la seccion 6.4.1.1 se puede sacar de forma sencilla la

implementacion.

Con las consultas SQL que se muestran a continuacion se crean las tablas de la base

de datos General, y para cada tabla tambien se crean los ındices necesarios. Estos ındices

valdran para realizar consultas mas rapidas en esas tablas, por lo que se centraran en

aquellos atributos por los que luego se haran busquedas mas a menudo.

-- --------------------

-- CREATING TABLES

-- --------------------

CREATE TABLE Persona (

Dni_Pas Varchar(50) NOT NULL ,

E_mail Varchar(255) NOT NULL ,

Usuario_Conf Bit NOT NULL ,

Page 218: Xesthproyecto

7.2. Implementacion de las Base de Datos 186

Nom_Usuario Varchar(255) NOT NULL ,

Password Varchar(255) NOT NULL ,

Nombre Varchar(255) NOT NULL ,

Apellidos Varchar(255) NOT NULL ,

Dir_Calle Varchar(255),

Pais Varchar(255),

Cliente Bit NOT NULL ,

Telefono1 Varchar(100),

Telefono2 Varchar(100),

Fecha_Nac TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,

CONSTRAINT pk_Persona PRIMARY KEY (Dni_Pas)) Type= INNODB;

CREATE UNIQUE INDEX indice_Nom_Usuario

ON Persona(Nom_Usuario);

CREATE INDEX indice_Nombre

ON Persona(Nombre);

CREATE INDEX indice_Apellidos

ON Persona(Apellidos);

CREATE INDEX indice_Fecha_Nac

ON Persona(Fecha_Nac);

CREATE TABLE Factura (

Dni_Pas Varchar(50) NOT NULL ,

Numero_Factura BigInt NOT NULL AUTO_INCREMENT ,

Fecha TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,

Total_Descontado Double NOT NULL ,

Total Double NOT NULL ,

Pagada Bit NOT NULL ,

Borrador Bit NOT NULL ,

Page 219: Xesthproyecto

7.2. Implementacion de las Base de Datos 187

Ofertas_Aplicadas Varchar(255) NOT NULL ,

CONSTRAINT pk_Factura PRIMARY KEY (Numero_Factura),

CONSTRAINT fk_Dni_Pas_Factura FOREIGN KEY (Dni_Pas)

REFERENCES Persona(Dni_Pas)) Type= INNODB;

CREATE INDEX Indice_Dni_Pas_Factura

ON Factura(Dni_Pas);

CREATE INDEX Indice_Fecha_Factura

ON Factura(Fecha);

CREATE TABLE Reserva (

Dni_Pas Varchar(50) NOT NULL ,

Codigo BigInt NOT NULL AUTO_INCREMENT ,

Fecha_Realizacion TimeStamp NOT NULL DEFAULT

CURRENT_TIMESTAMP ,

Temporal Bit NOT NULL ,

CONSTRAINT pk_Reserva PRIMARY KEY (Codigo),

CONSTRAINT fk_Dni_Pas_Reserva FOREIGN KEY (Dni_Pas)

REFERENCES Persona(Dni_Pas)) Type= INNODB;

CREATE INDEX Indice_Dni_Pas_Reserva

ON Reserva(Dni_Pas);

CREATE INDEX Indice_Fecha_Reserva

ON Reserva(Fecha_Realizacion);

CREATE TABLE Habitacion (

Numero MediumInt NOT NULL ,

Piso SmallInt NOT NULL ,

Precio_Extra Double NOT NULL DEFAULT 0,

Page 220: Xesthproyecto

7.2. Implementacion de las Base de Datos 188

CONSTRAINT pk_Habitacion PRIMARY KEY (Numero)) Type= INNODB

;

CREATE TABLE Lineas_de_Reserva (

Codigo_Reserva BigInt NOT NULL ,

Numero MediumInt NOT NULL ,

Fecha_Inicio TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,

Fecha_Fin TimeStamp NOT NULL ,

Descuento Double NOT NULL ,

Total_Parcial Double NOT NULL ,

Numero_Factura BigInt NOT NULL ,

Cancelada Bit NOT NULL ,

CONSTRAINT pk_Lineas_de_Reserva PRIMARY KEY (Codigo_Reserva

, Numero, Fecha_Inicio),

CONSTRAINT fk_Numero_Lineas_de_Reserva FOREIGN KEY (Numero)

REFERENCES Habitacion (Numero),

CONSTRAINT fk_Codigo_Reserva_Lineas_de_Reserva FOREIGN KEY

(Codigo_Reserva) REFERENCES Reserva(Codigo),

CONSTRAINT fk_Numero_Factura_Lineas_de_Reserva FOREIGN KEY

(Numero_Factura) REFERENCES Factura( Numero_Factura))

Type= INNODB;

CREATE INDEX Indice_Codigo_Reserva_Lineas_de_Reserva

ON Lineas_de_Reserva(Codigo_Reserva);

CREATE INDEX Indice_Numero_Factura_Lineas_de_Reserva

ON Lineas_de_Reserva(Numero_Factura);

CREATE TABLE Tipo_Habitacion (

Id_Tipo MediumInt NOT NULL AUTO_INCREMENT ,

Descripcion Text ,

Num_Personas SmallInt ,

Page 221: Xesthproyecto

7.2. Implementacion de las Base de Datos 189

Precio_Base Double NOT NULL ,

CONSTRAINT pk_Tipo_Habitacion PRIMARY KEY (Id_Tipo)) Type=

INNODB;

CREATE TABLE Es_de_tipo (

Numero MediumInt NOT NULL ,

Id_Tipo MediumInt NOT NULL ,

CONSTRAINT pk_Es_de_tipo PRIMARY KEY (Numero, Id_Tipo),

CONSTRAINT fk_Numero_Habitacion FOREIGN KEY (Numero)

REFERENCES Habitacion(Numero),

CONSTRAINT fk_Id_Tipo_Tipo_Habitacion FOREIGN KEY (Id_Tipo)

REFERENCES Tipo_Habitacion(Id_Tipo)) Type= INNODB;

CREATE INDEX Indice_Id_Tipo_Es_de_tipo

ON Es_de_tipo(Id_Tipo);

CREATE INDEX Indice_Numero_Es_de_tipo

ON Es_de_tipo(Numero);

CREATE TABLE Incidencia (

Numero MediumInt NOT NULL ,

Id_Secundario MediumInt NOT NULL ,

Tipo Varchar(255),

Descripcion Text ,

Fecha_Registro TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP

,

CONSTRAINT pk_Incidencia PRIMARY KEY (Numero, Id_Secundario

),

CONSTRAINT fk_Numero_Habitacion_Incidencia FOREIGN KEY (

Numero) REFERENCES Habitacion(Numero)) Type= INNODB;

CREATE INDEX Indice_Numero_Incidencia

Page 222: Xesthproyecto

7.2. Implementacion de las Base de Datos 190

ON Incidencia(Numero);

-- --------------------

-- Insert Admin

-- --------------------

INSERT INTO Persona (Dni_Pas , E_mail, Usuario_Conf , Nom_Usuario ,

Password , Nombre, Apellidos , Dir_Calle , Pais , Cliente , Telefono1

, Telefono2)

VALUES (’0’, ’’, 1,’admin’, ’admin’, ’’, ’’, ’’, ’’, 0, ’’,

’’);

-- --------------------

-- Insert Receptionist

-- --------------------

INSERT INTO Persona (Dni_Pas , E_mail, Usuario_Conf , Nom_Usuario ,

Password , Nombre, Apellidos , Dir_Calle , Pais , Cliente , Telefono1

, Telefono2)

VALUES (’1’, ’’, 1, ’receptionist’, ’receptionist’, ’’, ’’,

’’, ’’, 0, ’’, ’’);

7.2.2. Implementacion de la Base de Datos de Ofertas

Despues de realizar el diseno que se ha detallado en la seccion 6.4.1.2 ya se pueden crear

directamente las consultas SQL para construir esta base de datos, y ademas, como en el

caso de la base de datos General, crear los ındices necesarios para optimizar las futuras

busquedas. Las consultas que finalmente hay que ejecutar para tales objetivos son las

siguientes:

-- --------------------

Page 223: Xesthproyecto

7.2. Implementacion de las Base de Datos 191

-- Base de datos Oferta:

-- --------------------

CREATE TABLE Tipo_Oferta (

Id_Tipo MediumInt NOT NULL AUTO_INCREMENT ,

Nombre Varchar(255),

Descripcion Text ,

CONSTRAINT pk_Tipo_Oferta PRIMARY KEY (Id_Tipo)) Type=

INNODB;

CREATE INDEX Indice_Nombre_Tipo_Oferta

ON Tipo_Oferta(Nombre);

CREATE TABLE Oferta (

Id_Oferta MediumInt NOT NULL AUTO_INCREMENT ,

Descuento Double NOT NULL ,

Descripcion Text ,

Fecha_Inicio TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,

Fecha_Fin TimeStamp NOT NULL ,

Regla_a_cumplir Text ,

Id_Tipo MediumInt NOT NULL ,

Borrador Bit NOT NULL ,

Desactivada Bit NOT NULL ,

CONSTRAINT pk_Oferta PRIMARY KEY (Id_Oferta),

CONSTRAINT fk_Id_Tipo_Tipo_Oferta FOREIGN KEY (Id_Tipo)

REFERENCES Tipo_Oferta(Id_Tipo)) Type= INNODB;

CREATE INDEX Indice_Id_Tipo_Oferta

ON Oferta(Id_Tipo);

CREATE TABLE Aplicable_A (

Id_Tipo MediumInt NOT NULL ,

Nombre Varchar(255) NOT NULL ,

Page 224: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 192

Cantidad_Min MediumInt NOT NULL DEFAULT 1,

CONSTRAINT pk_Aplicable_A PRIMARY KEY (Id_Tipo , Nombre))

Type= INNODB;

CREATE INDEX Indice_Id_Tipo_Aplicable_A

ON Aplicable_A(Id_Tipo);

CREATE TABLE Incompatible_Con (

Id_Tipo MediumInt NOT NULL ,

Id_Tipo_Incomp MediumInt NOT NULL ,

CONSTRAINT pk_Incompatible_Con PRIMARY KEY (Id_Tipo ,

Id_Tipo_Incomp),

CONSTRAINT fk_Id_Tipo_Incompatible_Con FOREIGN KEY (Id_Tipo

) REFERENCES Tipo_Oferta(Id_Tipo),

CONSTRAINT fk_Id_Tipo_Incomp_Incompatible_Con FOREIGN KEY (

Id_Tipo_Incomp) REFERENCES Tipo_Oferta(Id_Tipo)) Type=

INNODB;

CREATE INDEX Indice_Id_Tipo_Incompatible_Con

ON Incompatible_Con(Id_Tipo);

CREATE INDEX Indice_Id_Tipo_Incomp_Incompatible_Con

ON Incompatible_Con(Id_Tipo_Incomp);

7.3. Implementaciones del Sistema de Ofertas

7.3.0.1. Implementacion de Factorıa de Partes de Regla

En esta seccion se muestra como se realizo finalmente la implementacion de la clase

RulePartFactory, que se encarga de crear las partes de regla despues de que la clase Regla

la haya parseado.

Page 225: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 193

1 package hotel.modelo.modelooferta.calculadordeoferta.regla;

2

3 import java.io.BufferedReader;

4 import java.io.FileNotFoundException;

5 import java.io.IOException;

6 import java.io.InputStream;

7 import java.io.InputStreamReader;

8 import java.util.ArrayList;

9 import java.util.Collection;

10 import java.util.Iterator;

11

12 import hotel.util.configuration.ConfigurationParametersManager ;

13 import hotel.util.exceptions.model.

MissingConfigurationParameterException ;

14

15 @SuppressWarnings("unchecked")

16 public class RulePartFactory {

17

18

19 private static Collection <String > availableRuleParts = null;

20 private final static String availableRulePartsFile = "

RulePartFactory/file";

21

22 static {

23

24 availableRuleParts = new ArrayList <String >();

25 String temp = null;

26 try {

27 Class myClass = RulePartFactory.class;

28 ClassLoader classLoader =

29 myClass.getClassLoader();

Page 226: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 194

30 InputStream inputStream = classLoader.

getResourceAsStream(

31 ConfigurationParametersManager .getParameter(

availableRulePartsFile));

32 InputStreamReader in = new InputStreamReader(

inputStream);

33 BufferedReader fileBuffer = new BufferedReader(in);

34

35 while ((temp = fileBuffer.readLine())!=null) {

36 if (!temp.equals("")) {

37 availableRuleParts.add(temp);

38 }

39 }

40 } catch (FileNotFoundException e) {

41 System.out.println("ValidValuesFile Not Found");

42 } catch (IOException e) {

43 System.out.println("Unabled to read ValidValuesFile");

44 } catch ( MissingConfigurationParameterException e) {

45 System.out.println("Configuration parameter Not Found")

;

46 }

47 }

48

49 public Collection <String > getValidRuleParts() {

50

51 return availableRuleParts;

52 }

53

54 public static RulePart getRulePart(String key , String [] args) {

55

56 if (existsRulePart(key)){

57 try {

Page 227: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 195

58 Class concreteClass = null;

59 String className =

ConfigurationParametersManager .

getParameter(

60 "RulePartFactory/" + key);

61 concreteClass = Class.forName(className);

62 RulePart r = (RulePart) concreteClass.

newInstance();

63 r.setArgs(args);

64 return r;

65 } catch (MissingConfigurationParameterException e)

{

66 return null;

67 } catch (ClassNotFoundException e) {

68 return null;

69 } catch (IllegalArgumentException e) {

70 return null;

71 } catch (SecurityException e) {

72 return null;

73 } catch (InstantiationException e) {

74 return null;

75 } catch (IllegalAccessException e) {

76 return null;

77 }

78 }

79 else return null;

80 }

81

82 public static RulePart getRulePart(String key) {

83 /*

84 * Igual al metodo anterior , solo que este crear un

85 * nuevo RulePart sin argumentos

Page 228: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 196

86 */

87 }

88

89 public static boolean existsRulePart(String key) {

90 Iterator <String> iter = availableRuleParts.iterator();

91 String aux = "";

92 boolean cent = false;

93 while (iter.hasNext()) {

94 aux = iter.next();

95 if (aux.compareTo(key)==0) {

96 cent = true;

97 }

98 }

99 return cent;

100 }

101 }

7.3.0.2. Implementacion de Calculador

Los pasos que realiza el metodo ’calcularMejorPara’ del objeto Calculador, se pueden

observar claramente con el trozo de codigo fuente que los realiza:

1 public Collection <Ofertable > CalcularMejorPara(Connection c,

2 Collection <Ofertable > colOfertable , String

dniPasPersona)

3 throws InternalErrorException {

4

5 //Aqui dividimos la coleccion de Ofertables inicial en

OfertableCollections segun su tipo

6

7 split(colOfertable);

8

Page 229: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 197

9 SQLOfertaDAO OF = SQLOfertaDAOFactory.getDAO ();

10

11 //Recuperamos TODA la lista de ofertas posibles

12

13 Collection <OfertaVO > colOferta = new ArrayList <OfertaVO >();

14 Collection <OfertaVO > temp;

15 int i = 1;

16 while ((temp = OF. getByDesactivada(c, false , i, 21)).

size()==21){

17 temp.remove (20);

18 colOferta.addAll(temp);

19 i=i+20;

20 }

21 if (temp.size() <21) {

22 colOferta.addAll(temp);

23 }

24 //Fin recuperacion lista

25

26 //Ahora nos quedamos solo con las que son aplicables segun

nuestra regla

27

28 ArrayList <OfertaVO > ofAplicables = new ArrayList <OfertaVO

>();

29 ArrayList <OfertaVO > alOferta = new ArrayList <OfertaVO >();

30 alOferta.addAll(colOferta);

31 Iterator <OfertaVO > iterOf = alOferta.iterator();

32 OfertaVO myOfAux = null;

33 while (iterOf.hasNext()) {

34 myOfAux = iterOf.next();

35 if (canBeApplied(myOfAux , colDeCol , dniPasPersona)) {

36 ofAplicables.add(myOfAux);

37 }

Page 230: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 198

38 }

39 //Ya solo nos quedan las que podemos aplicar segun nuetra

regla

40

41 //Y ahora llamamos a nuestro calculador preferido para que

nos calcule

42

43 Collection <Ofertable > col =

44 this.calculador.calculaMejorOferta(colDeCol ,

ofAplicables);

45 this.colOfApplied = this.calculador. getAppliedOffers();

46 return col;

47 }

En el siguiente trozo de codigo se puede ver como es el funcionamiento basico del metodo

’calculaMejorOferta’ de la clase CalculadorImpl, ya que para realizar ciertas operaciones

delega su funcionamiento en otro metodo auxiliar:

1 public Collection <Ofertable > calculaMejorOferta(

2 Collection <OfertableCollectionChunkVO > colProductos ,

3 Collection <OfertaVO > colOfertasPosibles)

4 throws InternalErrorException {

5

6 // Primero hay que dividir las ofertas por tipos , ya que de

cada tipo solo se va a poder aplicar una y solo una

oferta.

7

8 Map <Long , ArrayList <OfertaVO >> byTipo =

9 new HashMap <Long , ArrayList <OfertaVO >>();

10 Iterator <OfertaVO > iter = colOfertasPosibles.iterator();

11 OfertaVO ofAux = null;

12 while (iter.hasNext()) {

Page 231: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 199

13 ofAux = iter.next();

14 if (byTipo.containsKey(ofAux.getIdTipo())) {

15 byTipo.get(ofAux.getIdTipo()).add(ofAux);

16 }

17 else {

18 ArrayList <OfertaVO > a = new ArrayList <OfertaVO >();

19 a.add(ofAux);

20 byTipo.put(ofAux.getIdTipo(), a);

21 }

22 }

23

24 Map <Long , Double > offerTypeVsDiscount = new HashMap <Long ,

Double >();

25

26 //Recorro todos los tipos de ofertas , calculo el maximo

descuento que se puede hacer sobre los ofertables que me

pasan y anhado estos valores al mapa , para que luego mi

optimizador (BestSetOfOffers) me devuelva las que se

pueden apicar para que produzcan el mayor descuento.

27

28 Collection <Long > tipos = byTipo.keySet ();

29 Iterator <Long > tiposIter = tipos.iterator();

30 Long longAux = null;

31 OfertaVO bestAux = null;

32 while (tiposIter.hasNext()) {

33 longAux = tiposIter.next();

34 bestAux = this.getBestOffer(byTipo.get(longAux));

35 this.myProxyMap.put(longAux , bestAux);

36 }

37

38 tipos = this.myProxyMap.keySet ();

39 tiposIter = tipos.iterator();

Page 232: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 200

40 while (tiposIter.hasNext()) {

41 longAux = tiposIter.next();

42 offerTypeVsDiscount.put(longAux , this.

getAmountDiscounted(colProductos ,

43 this.myProxyMap.get(longAux)));

44

45 }

46

47

48 try {

49 BestSetOfOffers bestOffers = new BestSetOfOffers(

offerTypeVsDiscount);

50 this. myBestSetOfOffersTypes = bestOffers.

getBestSetOfOffersIds();

51 Iterator <Long > iterBest = this.myBestSetOfOffersTypes.

iterator();

52

53 while (iterBest.hasNext()) {

54 this. acumularOfertaEnOfertableCollection (

colProductos ,

55 this.myProxyMap.get(iterBest.next()));

56 }

57

58 //Ahora anhado todos los ofertables

59

60 Iterator <OfertableCollectionChunkVO > iterOfertableCol =

61 colProductos.iterator();

62 while (iterOfertableCol.hasNext()) {

63 this. myFinalOfertableCol.addAll(

64 iterOfertableCol.next().

extractOfertableCollection ());

65 }

Page 233: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 201

66

67 } catch ( InternalErrorException e) {

68 throw e;

69 } catch (SQLException e) {

70 throw new InternalErrorException("SQL Exception: in

SimpleCalculator");

71 }

72

73 return this. myFinalOfertableCol;

74 }

7.3.0.3. Implementacion de una Parte de Regla

No hay mejor forma de ver como se implementarıa una nueva parte de regla es con

un ejemplo, ası que a continuacion se muestra la implementacion de la parte de regla

PersonBornBefore, la forma de crear una nueva es analoga a esta.

1 package hotel.modelo.modelooferta.calculadordeoferta.regla.partes;

2

3 import java.util.Calendar;

4 import java.util.Collection;

5 import javax.sql.DataSource;

6 import hotel.modelo.modelooferta. calculadordeoferta.regla.RulePart;

7 import hotel.modelo.modelooferta.oferta.vo.OfertaVO;

8 import hotel.modelo.modelooferta.util.ofertablecollection.

OfertableCollectionChunkVO;

9 import hotel.modelo.persona.dao.SQLPersonaDAO;

10 import hotel.modelo.persona.dao.SQLPersonaDAOFactory;

11 import hotel.util.sql.GeneralDataSource;

12

13 public class PersonBornBefore implements RulePart {

Page 234: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 202

14

15 private Integer day ;

16 private Integer month;

17 private Integer year;

18

19 public PersonBornBefore () {}

20

21 public void setArgs (String [] args) {

22 day = new Integer(args[0]);

23 month= new Integer(args[1]);

24 year = new Integer(args[2]);

25 }

26

27 public boolean isRulePartApplicableTo(OfertaVO of,

28 Collection <OfertableCollectionChunkVO > colDeCol , String

dniPas) {

29 try {

30 System.out.println("entro");

31 SQLPersonaDAO persDAO = SQLPersonaDAOFactory.getDAO ();

32 DataSource ds = new GeneralDataSource();

33 Calendar fechaNacimiento = persDAO.findPersona(ds.

getConnection(),

34 dniPas).getFechaNac();

35 Calendar c = Calendar.getInstance();

36 c.clear();

37 c.set(year , month -1, day);

38 c.setLenient(false);

39 c.getTime();

40 System.out.println(c.toString());

41 System.out.println( fechaNacimiento.toString());

42 return c.compareTo( fechaNacimiento) >=0;

43 } catch (Exception e) {

Page 235: Xesthproyecto

7.3. Implementaciones del Sistema de Ofertas 203

44 return false;

45 }

46 }

47

48 public boolean isCorrect(String [] args) {

49 if (args.length ==3) {

50 if (args [0]!= null&&(args[0]. compareTo("")!=0)

51 &&args[1]!= null&&(args[1]. compareTo("")!=0)

52 &&args[2]!= null&&(args[2]. compareTo("")!=0)) {

53 try {

54 Integer day = new Integer(args [0]);

55 Integer month= new Integer(args [1]);

56 Integer year = new Integer(args [2]);

57 Calendar c = Calendar.getInstance();

58 c.clear();

59 c.set(year , month -1, day);

60 c.setLenient(false);

61 c.getTime();

62 return true;

63 }

64 catch (Exception e) {

65 return false;

66 }

67 }

68 else return false;

69 }

70 else if (args.length <3) {

71 return false;

72 }

73 else {

74 for (int i=3;i<args.length;i++) {

75 if ((args[i]!=null)&&(args[i]. compareTo("")!=0)) {

Page 236: Xesthproyecto

7.4. Software Necesario para Desplegar la Aplicacion 204

76 return false;

77 }

78 }

79 }

80 return true;

81 }

82 }

7.4. Software Necesario para Desplegar la Aplicacion

Para que la aplicacion funcione correctamente se necesita tener instalado el siguiente

software.

Maquina virtual Java SE 6.0

Es necesario tener intalada la maquina virtual de Java SE 6.0 o posterior ya que fue

esta la utilizada en la compilacion de la aplicacion.

Servidor de Aplicaciones Web Apache Tomcat 6.0.20

Es necesario tener intalado un servidor de aplicaciones web, en este caso se utilizara el

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 version 5.0 o

superior, para almacenar las bases de datos necesarias para el funcionamiento del

sistema desarrollado.

7.4.1. Instalacion y Configuracion del Software Necesario

Junto con la aplicacion se provee ademas del sofware que esta necesita para funcionar, a

continuacion se explica brevemente como intalarlo y configurarlo. El desarrollo e instala-

Page 237: Xesthproyecto

7.4. Software Necesario para Desplegar la Aplicacion 205

cion de esta aplicacion se realizo en un entorno Linux, concretamente en una distribucion

’Ubuntu 8.10’, por lo que se realizara la explicacion para este sistema operativo.

Para instalar el software se creara un directorio llamado ’software’ dentro de la carpeta

personal del usuario.

Maquina virtual Java SE 6.0

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 anadimos

al PATH, anadiendo las siguientes lıneas al final del fichero de configuracion del

interprete de comandos, en este caso sera en ’$HOME/.bashrc’:

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/

3. Exportar la variable de entorno CATALINA HOME, y la anadimos al PATH,

anadiendo la siguiente lınea al final del fichero de configuracion del interprete

de comandos, en este caso sera en ’$HOME/.bashrc’:

1 CATALINA_HOME=$HOME /software /apache -tomcat -6.0.20/

2 export CATALINA_HOME

3 PATH= $CATALINA_HOME/bin:$PATH

Page 238: Xesthproyecto

7.4. Software Necesario para Desplegar la Aplicacion 206

4. Una vez instalado se procede a su configuracion anadiendo la siguiente lınea en

su fichero de configuracion ($HOME/software/apache-tomcat-6.0.20/conf/tomcat-

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 ’shut-

down.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 debera almacenar las bases de datos, por

ejemplo, $HOME/.MyDATA .

4. Se crea un fichero de configuracion para MySQL en $HOME/.my.cnf con el

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-linux-

i686-glibc23/ y ejecutar el siguiente comando para crear las bases de datos

’mysql’ y ’test’:

1 scripts / mysql_install_db

6. Exportar la variable de entorno MYSQL HOME, y la anadimos al PATH,

anadiendo la siguiente lınea al final del fichero de configuracion del interprete

de comandos, en este caso sera en ’$HOME/.bashrc’:

Page 239: Xesthproyecto

7.4. Software Necesario para Desplegar la Aplicacion 207

1 MYSQL_HOME =$HOME/ software /mysql -5.0.67 - linux -i686 -glibc23

2 export MYSQL_HOME

3 PATH= $MYSQL_HOME /bin:$PATH

7. Una vez exportadas las variables de entorno hay que proceder al arranque del

gestor ejecutando el siguiente comando:

1 mysqld

8. Despues de arrancar el servidor de MySQL hay que crear la base de datos que

va a utilizar la aplicacion y darle permisos a esta, para crear la base de datos

se utilizara el comando:

1 mysqladmin -u root create bd_hotel

A continuacion se entra en la consola de MySQL para crear un nuevo y usuario

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 PRIVILEGES ON bd_hotel .*

2 TO hotelapp@localhost IDENTIFIED BY ’hotelapp ’,

3 [email protected] IDENTIFIED BY ’hotelapp ’;

9. Para parar el servidor de MySQL se ejecuta lo siguiente:

1 mysqladmin -u root shutdown

Herramienta Maven para Gestion de Proyectos

Esta herramienta no es necesario instalarla para que la aplicacion funcione, pero es

de gran utilidad para futuras modificaciones o desarrollos.

Page 240: Xesthproyecto

7.5. Organizacion de los Directorios del Proyecto 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 anadimos al PATH,

anadiendo la siguiente lınea al final del fichero de configuracion del interprete

de comandos, en este caso sera en ’$HOME/.bashrc’:

1 MAVEN_HOME =$HOME/software /apache -maven -2.2.1

2 export MAVEN_HOME

3 PATH=$MAVEN_HOME /bin :$PATH

4. Una vez exportado el PATH ya se puede utilizar el comando ’mvn’ para arran-

carlo.

7.5. Organizacion de los Directorios del Proyecto

Para la realizacion de este proyecto se ha mantenido la estructura fundamental generada

por la herramienta Maven 2 para proyectos web. Dentro de esta estructura se organizan

todos los elementos necesarios para el funcionamiento de la aplicacacion, de la siguiente

forma:

En /j2ee-hotel-app/src/main/java/es/udc/j2eehotelapp/hotel se encuentran las clases

del modelo de la aplicacion, los DAO, las fachadas, y el modelo del sistema de ofertas.

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 en-

cuentran los ficheros de las traducciones utilizadas para la internacionalizacion.

Page 241: Xesthproyecto

7.6. Instrucciones de Compilacion y Despliegue 209

En /j2ee-hotel-app/src/main/resources estan los ficheros utilizados para la configura-

cion de la aplicacion y para configurar las reglas del sistema de ofertas.

En /j2ee-hotel-app/src/main/webapp se encuentra, divididos en subdirectorios segun el

usuario que vaya a hacer uso de ellas, las paginas JSP utilizadas para mostrar la IU de la

aplicacion.

En /j2ee-hotel-app/src/main/webapp/WEB-INF es donde estan los diferentes ficheros

de configuracion del servidor (web.xml), de Struts (plain-struts-config.xml) y de Tiles

(tiles-defs.xml).

7.6. Instrucciones de Compilacion y Despliegue

Estos pasos se explicaran desde dos puntos de vista, tener instalado Maven 2 o no tenerlo

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 utilizara el comando ’mysqld’.

A continuacion, en caso de no tener instalado Maven se procede a crear las tablas

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 instalacion, ’startup.sh’

En la distribucion de este proyecto se entregan dos versiones, una para el desarrollo

con Maven y otra para el desarrollo sin el. Si se esta utilizando Maven, el proyecto se en-

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 aplicacion:

Page 242: Xesthproyecto

7.6. Instrucciones de Compilacion y Despliegue 210

’mvn clean’ para eliminar cualquier compilacion anterior.

’mvn package’ para compilar y generar el .war para desplegar.

En caso de no utilizar Maven, se usaran los proyectos contenidos en ’hotel’ y ’hotel-app’.

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 aplicacion y es compilado automaticamente por eclipse. Por otro lado se encuentra

el proyecto ’hotel’ donde estan las paginas JSP, la configuracion de struts, etc. Para que

este segundo proyecto funcione correctamente se debe crear una librerıa .jar del primer

proyecto y copiarla en la raiz de este. Una vez realizado esto hay que proceder a generar

el fichero .war, para lo que se utilizara la herramienta ’jar’, se posiciona justo fuera de

’hotel’ y se ejectuta ’jar cvfm hotel.war hotel’.

Cuando se haya generado el paquete .war se copia en el directorio webapps de la ins-

talacion de Apache Tomcat y para ejecutarlo simplemente se abre el navegador web y se

especifica la siguiente URL: http://localhost:8080/nombrePaquete.

Page 243: Xesthproyecto

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 utilizo el framework JUnit, estas pruebas se realizar para probar que

ante una entrada determinada en un metodo, este siempre devuelve lo esperado.

Se realizaron pruebas de unidad de todos los objetos DAO de sus metodos mas im-

portantes para comprobar que todo el intercambio de informacion con la base de datos

se realizaba correctamente, posteriormente, a medida que se fueron desarrollando las dis-

tintas fachadas del modelo se realizaban pruebas de unidad de los metodos que serıan

utilizados mas frecuentemente y aquellos que realizasen operaciones mas complejas y ver,

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 grafica, una vez

hecho esto se hacen diversas pruebas para comprobar que todo funciona conforme a las

especificaciones establecidas por el usuario.

Dos de los casos mas complejos que hubo que probar fueron, la realizacion de reservas,

y que el sistema de ofertas calculase correctamente el descuento para una factura. En

el primer caso se cubrieron todos los pasos posibles de realizacion de reservas: en varios

211

Page 244: Xesthproyecto

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ıa que probar era que calculase

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 calculos pertinentes a mano, y se comprobo que el resutado

calculado por el sistema de ofertas era el esperado en todos los casos de prueba.

Page 245: Xesthproyecto

Capıtulo 9

Planificacion y Evaluacion de

Costes

En este capıtulo se muestra la planificacion del proyecto teniendo en cuenta las fases

de la metodologıa descrita por el Proceso Unificado. Estas fases se han detallado en el

apartado 4.2. Y se puede observar de forma grafica como se preceden unas a otras en el

grafico de Gantt de la figura 9.1. Ademas tambien se puede ver con claridad como hay

en ciertas ocasiones en las cuales se pueden estar realizando dos tareas simultanemente,

estableciendose de esa forma una relacion comienzo-comienzo entre ellas.

Ademas de indicar la planificacion de las diferentes tareas que forma el desarrollo del

proyecto, tambien se hace una evaluacion de los costes de realizacion de dichas tareas.

Para cada tarea se necesita uno o varios empleados, y para la realizacion de este proyecto

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ıa (5 horas/dıa), 5 dıas a la semana.

A continuacion, en la tabla 9.1 se muestra la planificacion de las diferentes tareas y el

coste asociado a cada una de ellas.

213

Page 246: Xesthproyecto

214

Id Tarea Nombre Inicio Fin Duracion Coste (e) Asignada a

1 Concepcion Abr 14 Abr 20 5d 600 e1.1 + Iteracion 1 (I) Abr 14 Abr 20 5d 600 e1.1.1 ++ Modelado de Negicio (I1) Abr 14 Abr 14 1d 100 e Analista1.1.2 ++ Analisis de Requisitos (I1) Abr 15 Abr 15 1d 100 e Analista1.1.3 ++ Diseno (I1) Abr 16 Abr 16 1d 100 e Analista1.1.4 ++ Implementacion/Pruebas (I1) Abr 17 Abr 20 2d 300 e Programador2 Elaboracion Abr 21 May 1 9d 1100 e2.1 + Iteracion 1 (E) Abr 21 May 1 9d 1100 e2.1.1 ++ Analisis de Requisitos (E1) Abr 21 Abr 22 2d 200 e Analista2.1.2 ++ Diseno (E1) Abr 23 Abr 27 3d 300 e Analista2.1.3 ++ Implementacion/Pruebas (E1) Abr 28 May 1 4d 600 e Programador3 Construccion May 4 Jul 24 60d 10410 e3.1 + Iteracion 1 (C) May 4 May 22 14d 4h 2280 e3.1.1 ++ Analisis de Requisitos (C1) May 4 May 4 4h 80 e Analista3.1.2 ++ Diseno (C1) May 4 May 8 4d 400 e Analista3.1.3 ++ Implementacion/Pruebas (C1) May 6 May 22 12d 1800 e Programador3.2 + Iteracion 2 (C) May 22 Jun 19 20d 1h 3800 e3.2.1 ++ Analisis de Requisitos (Sistema Ofertas) (C2) May 22 May 25 1d 100 e Analista3.2.2 ++ Diseno (Sistema Ofertas) (C2) May 25 May 28 3d 300 e Analista3.2.3 ++ Diseno (C2) May 22 May 28 4d 400 e Analista3.2.4 ++ Implementacion/Pruebas (C2) May 25 Jun 19 20d 3000 e Programador3.3 + Iteracion 3 (C) Jun 22 Jul 24 25d 4330 e3.3.1 ++ Analisis de Requisitos (Sistema Reglas) (C3) Jun 22 Jun 22 4h 80 e Analista3.3.2 ++ Diseno (Sistema Reglas) (C3) Jun 22 Jun 24 2d 200 e Analista3.3.3 ++ Diseno (C3) Jun 22 Jun 24 3d 300 e Analista3.3.4 ++ Implementacion/Pruebas (C3) Jun 22 Jul 24 25d 3750 e Programador4 Transicion Jul 27 Jul 31 5d 725 e4.1 + Iteracion 1 (T) Jul 27 Jul 31 5d 725 e4.1.1 ++ Despliegue (T1) Jul 27 Jul 27 1d 150 e Programador4.1.2 ++ Documentacion de Usuario (T1) Jul 27 Jul 31 5d 575 e Analista, Programador

Total PROYECTO Abr 14 Jul 31 79d 12835 e Analista, Programador

Cuadro 9.1: Planificacion - Tabla de Tareas

Page 247: Xesthproyecto

215Figura 9.1: Planificacion - Diagrama de Gantt

Page 248: Xesthproyecto
Page 249: Xesthproyecto

Capıtulo 10

Conclusiones y Futuras Lıneas de

Trabajo

Al termino del desarrollo de este proyecto se puede decir que se han cumplido todos los

objetivos que habıa que alcanzar con su realizacion.

Uno de los objetivos principales era el aprendizaje de la plataforma J2EE para el desa-

rrollo de aplicaciones web, ası como del resto de tecnologıas especificadas en el capıtulo 1,

alcanzando ası los conocimientos esperados.

Ademas del objetivo didactico, este proyecto cumple con las especificaciones y los re-

quisitos para los cuales estaba orientado. Aunque algunos de estos requisitos tenıan cierta

complejidad, se consiguio de igual forma llevarlos a cabo.

Entre los requisitos que deberıa cumplir destacan los siguientes:

La gestion de usuarios de la aplicacion funciona correctamente y conforme a lo

esperado, alta de nuevos usuarios, baja de usuario, modificacion de sus datos, etc.

Ademas para el recepcionista del hotel se le proporcionan funcionalidades para dar

de alta a nuevos clientes, modificar sus datos, o realizar una busqueda de un cliente

217

Page 250: Xesthproyecto

218

por varios campos a la vez, de esta forma el recepcionista podra seleccionar al cliente

que desee y trabajar con el.

La gestion de reservas, que era una de las partes algo complejas de la aplicacion, se

consiguio realizar con exito, en esta parte destaca que la seleccion de ofertas la hace

la aplicacion automaticamente despues de haber realizado la reserva, mientras que

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: Gestion de Reservas de Otra Aplicacion

A raız de estos funcionamientos poco correctos de las aplicaciones comerciales actua-

les, se decidio implementar un sistema de ofertas que se aplique automaticamente

cuando se realiza la reserva. Este fue el sistema, con diferencia, mas complejo de

toda la aplicacion, ya que hubo que definir un lenguaje de reglas para las ofertas y

un sistema de resolucion de incompatibilidades.

Ademas de estos subsistemas, se desarrollaron con exito los de gestion de habitacio-

nes, facturas y ofertas.

Page 251: Xesthproyecto

219

En futuras ampliaciones de este proyecto, se podrıa implementar un sistema de pago que

soporte el pago de una reserva a traves de diferentes medios, PayPal, tarjeta de credito,

etc.

Otra posible ampliacion serıa la realizacion de un gestor de contenido para el portal

del Hotel. Este gestor de contenido deberıa posibilidar la publicacion de noticias y su

internacionalizacion, y una gestion de las fotografıas de la galerıa.

Page 252: Xesthproyecto
Page 253: Xesthproyecto

Apendice A

Manuales para la Utilizacion de la

Aplicacion

Esta aplicacion es muy facil de utilizar e intuitiva, pero hay algunos aspectos, como las

operaciones que debe realizar el usuario que no lo son tanto y deben ser explicadas. Por

esta razon se crean estos manuales de usuario.

A.1. Manual Comun a Todos

Cuando se entra la aplicacion y aun no se ha autenticado, simplemente se ve la pagina

principal que contiene noticias y las ofertas disponibles actualmente, pero ademas de eso

el usuario que no esta autenticado solo podrıa acceder al contenido estatico del portal,

como puede ser la galerıa de imagenes.

La pagina principal, como se puede ver en la figura A.1 ofrece diversas operaciones,

aparte de navegar por el contenido estatico permite registrarse como nuevo usuario y

autentificarse si ya se esta registrado.

221

Page 254: Xesthproyecto

A.1. Manual Comun a Todos 222

Figura A.1: Pagina Principal del Portal

Si el usuario decide darse de alta debe hacer clic en donde pone ’Registrarse’ y esto lo

llevara al formulario de registro que se muestra en la figura A.2 que debe cubrir con sus

datos personales.

Figura A.2: Pagina Registro de Nuevo Usuario

Page 255: Xesthproyecto

A.1. Manual Comun a Todos 223

Si por otro lado el usuario ya esta registrado y desea entrar en la aplicacion, debera pin-

char sobre ’Autentificacion’ y esto lo llevara a la pagina de autentificacion que se muestra

en la figura A.3 donde ingresara su nombre de usuario en la aplicacion y su contrasena.

Figura A.3: Pagina Autentificacion

Una vez introducidos los datos, se le da a entrar y esto lleva al usuario a su pagina

principal, que variara dependiendo de su rol dentro del sistema, en este caso habra tres

tipos de usuarios distintos: Usuario/Cliente, Recepcionista y Administrador. Se mostraran

sus paginas principales en sus respectivos manuales de usuario.

Page 256: Xesthproyecto
Page 257: Xesthproyecto

A.2. Manual Especıfico para el Usuario 225

A.2. Manual Especıfico para el Usuario

Una vez autentificado en el sistema, se le presenta al usuario su pagina principal, como

se muestra en la figura A.4, donde podra elegir diversas acciones como: cambiar sus datos,

hacer nuevas reservas, consultar reservas, etc.

Figura A.4: Pagina Principal del Usuario

Aquı en la pagina principal se le muestran al usuario las distintas operaciones que puede

realizar en un panel lateral izquierdo, ordenadas por categorıas. Estas categorıas son:

’Personal’ y ’Reservas’.

’Personal’ contiene las siguientes operaciones: ’Actualizar info. registro’, ’Salir’ y ’Darse

de baja’. Y la categorıa de ’Reservas’ tiene: ’Nueva Reserva’ y ’Ver Reservas’.

A continuacion se explican cada una de las operaciones por separado:

Actualizar info. registro

Esta operacion presenta un formulario como el de la figura A.2 en el cual el usuario

podra cambiar la informacion de su perfil cuando desee. Ademas si quiere tambien

Page 258: Xesthproyecto

A.2. Manual Especıfico para el Usuario 226

podra cambiar su contrasena escribiendo simplemente una nueva, dejando ese campo

en blanco si no lo quiere hacer.

Salir

Esta operacion realiza la simple accion de salir de la cuenta, por lo que el usuario

deja de estar autentificado, si desea volver a entrar debera autentificarse de nuevo.

Darse de Baja

Esta operacion permite al usuario darse de baja en el sistema, pero antes de hacerlo

se le muestra una pagina de aviso como la de la figura A.5 en la que se le pregunta

si desea de verdad darse de baja, si responde afirmativamente, deja de estar dado de

alta en el sistema.

Figura A.5: Pagina de Aviso al Darse de Baja

Nueva Reserva

Esta operacion permite al usuario crear una nueva reserva para los dıas que desee.

El usuario podra anadir en una misma reserva, estancias para diferentes dıas y tipos

de habitacion, para realizar dicha operacion se le muestra un formulario como el de

la figura A.6.

Page 259: Xesthproyecto

A.2. Manual Especıfico para el Usuario 227

Figura A.6: Pagina para Realizar una Nueva Reserva

El usuario debe cumplimentar todos los campos, en primer lugar tiene que elegir el

tipo de habitacion que desea reservar, luego debe especificar la fecha de entrada y

de salida y por ultimo tiene que indicar el numero de habitaciones de ese tipo que

desea. Para anadir a la reserva la nueva estancia debera darle a ’Anadir’ o ’Anadir

y Finalizar’ si le da al boton de Anadir luego podra seguir creando nuevas estancias

para la reserva actual, y cuando lo desee le dara a ’Finalizar’ esto creara una nueva

reserva y comunicara al usuario el numero de esta para que la pueda consultar en

sus reservas mediante la operacion de ’Ver Reservas’.

Si en algun momento el usuario cumplimenta de forma erronea algun campo o no

hay habitaciones disponibles para cubrir su solicitud se le comunicara para que, si

lo desea pueda cambiar las preferencias de su estancia.

Ver Reservas

Esta operacion permite al usuario todas las reservas que haya realizado hasta el

momento, ya esten pagadas, canceladas o que ya se hayan disfrutado. Se mostraran

en forma de lista como se puede observar en la figura A.7 y si tuviese mas de diez

reservas se paginarıa el resultado. Ademas en cada una de las reservas se permite al

Page 260: Xesthproyecto

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 aun no se ha pagado ni disfrutado, modificarla.

Figura A.7: Pagina para Listar las Reservas

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 traves del cual

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 anadir nuevas

estancias es el mismo que el que se utilizaba en crear nueva reserva, pero con menos

botones ya que ahora solo seran necesarios ’Anadir’ y ’Cancelar’.

Ademas de modificar una reserva, en la lista tambien se ofrece la posibilidad de

cancelarla si aun no se ha disfrutado. Simplemente haciendo clic en ’Cancelar’ la

reserva queda cancelada y en la columna de total aparecera el recargo que se le

cobro al cliente por esta cancelacion si previamente la reserva habıa sido pagada.

Page 261: Xesthproyecto

A.2. Manual Especıfico para el Usuario 229

Figura A.8: Pagina para Modificar una Reserva

Por otro lado se puede observar la factura de una reserva haciendo clic en ’Factura’.

Si la factura ya se habıa pagado esta aparecera marcada como pagada, y si no lo

habıa sido se mostrara la opcion de pagar. Esto se muestra en la figura A.9.

Figura A.9: Pagina para Mostrar el Borrador de una Factura

Page 262: Xesthproyecto

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 calculo lo hace automaticamente el sistema. Si el importe

convence al cliente, este solo tendra que proceder al pago de la factura a traves del

boton ’Pagar’ y cuando el pago este realizado la factura se muestra como pagada

como en la figura A.10.

Figura A.10: Pagina para Mostrar una Factura Pagada

Page 263: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 231

A.3. Manual Especıfico para el Recepcionista

Una vez autentificado en el sistema, se le presenta al recepcionista su pagina principal,

como se muestra en la figura A.11, donde podra elegir diversas acciones como: cambiar

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: Pagina Principal del Recepcionista

Aquı en la pagina principal se le muestran al recepcionista las distintas operaciones que

puede realizar en un panel lateral izquierdo, ordenadas por categorıas. Estas categorı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 paginas 225 y 226. En la categorıa ’Habitaciones’

se muestra la operacion ’Ver habitaciones’ y en ’Clientes’ se muestran ’Nuevo Cliente’ y

’Buscar Cliente’.

Page 264: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 232

A continuacion se explican cada una de las operaciones por separado:

Ver Habitaciones

Esta operacion permite al recepcionista ver las habitaciones del hotel para luego

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: Pagina para Listar las Habitaciones para el Recpecionista

Para consultar los datos especıficos de un tipo de habitacion simplemente basta

con presionar el enlace sobre el tipo de habitacion y se mostraran los datos en un

formulario como el que se muestra en la figura A.13

Page 265: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 233

Figura A.13: Pagina para Mostrar los Datos de un Tipo de Habitacion

Nuevo Cliente

Esta operacion permite al recepcionista dar de alta a un nuevo cliente, para ello

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 explicara en

la siguiente operacion ’Buscar Cliente’

Page 266: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 234

Figura A.14: Pagina para Dar de Alta un Nuevo Cliente

Buscar Cliente

Esta operacion permite al recepcionista buscar a un cliente especificando parte o la

totalidad de su nombre, apellidos y/o DNI. Para realizarlo se le presenta un formula-

rio como el que se muestra en la figura A.15 en el cual introduce los parametros por

los que se desea buscar y se presiona el boton de ’Buscar’. Luego se muestra una lista

de los clientes que concuerdan con los parametros de busqueda como la de la figura

A.16 en donde proporciona la posibilidad de seleccionar el cliente que se desee para

trabajar con el, es decir, para poder realizarle reservas, consultarlas, etc. Una vez

seleccionado el cliente deseado se vuelve a la pagina principal del recepcionista, pero

en este caso se muestran opciones a mayores como se puede observar en la figura

A.17.

Page 267: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 235

Figura A.15: Pagina para Buscar Clientes

Figura A.16: Pagina para Listar los Clientes Buscados

Page 268: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 236

Figura A.17: Pagina Principal del Recepcionista Despues de Seleccionar Cliente

Como se puede observar ahora aumentan las categorıas y las operaciones que se

pueden realizar, puesto que ahora se pueden hacer cosas en nombre del cliente que

se ha seleccionado.

La nueva categorıa que aparece es ’Reservas’ en la cual aparecen las opciones de

’Nueva Reserva’ y ’Ver Reservas’. Ademas en la categorıa ’Clientes’ aparecen nuevas

operaciones como son: ’Ver/Actualizar Perfil del Cliente’, ’Cerrar Cuenta del Cliente’

o ’Dar de Baja Cliente’.

Nueva Reserva

Esta operacion permite al recepcionista realizar una reserva a peticion de un cliente,

el proceso que se sigue es el mismo explicado en la pagina 226 en la operacion ’Nueva

Reserva’.

Ver Reservas

Page 269: Xesthproyecto

A.3. Manual Especıfico para el Recepcionista 237

Esta operacion permite al recepcionista ver las reservas hechas por un cliente para,

en caso necesario, localizar y pagar o cancelar una reserva concreta a peticion de

un cliente. Estos procesos son exactamente iguales a los explicados para un usuario

normal en la operacion ’Ver Reservas’ en la pagina 227.

Ver/Actualizar Perfil del Cliente

Esta operacion permite al recepcionista ver la informacion del perfil de un cliente

y editarla si fuese necesario como si se tratase del propio cliente solo que no se

le permite, por ejemplo, cambiar la contrasena. Para ello se le presenta el mismo

formulario que el mostrado para realizar la operacion de ’Nuevo Cliente’ que se

puede ver en la pagina 233

Cerrar Cuenta del Cliente

Esta operacion permite al recepcionista cerrar la cuenta del cliente con el que esta tra-

bajando, pasando a su pagina principal como se mostraba en la figura A.11 de la

pagina 231. Si desea volver a trabajar con ese u otro cliente debera volver a buscarlo

y seleccionarlo.

Dar de Baja Cliente

Esta operacion permite al recepcionista dar de baja a un cliente del sistema a peticion

de este, tan pronto como lo haga se le mostrara un mensaje de aviso como el de la

figura A.5 de la pagina 226, indicando al recepcionista que debe alertar al cliente y

persuadirlo para que no se de de baja. Si el recepcionista confirma de todas formas

que desea realizar la operacion el cliente deja de estar dado de alta en el sistema y

por lo tanto se vuelve a la pagina principal del recepcionista de la figura A.11 de la

pagina 231.

Page 270: Xesthproyecto
Page 271: Xesthproyecto

A.4. Manual Especıfico para el Administrador 239

A.4. Manual Especıfico para el Administrador

Una vez autentificado en el sistema, se le presenta al administrdor su pagina principal,

como se muestra en la figura A.18, donde podra elegir diversas acciones como: cambiar

sus datos, crear y administrar las ofertas, dar de alta habitaciones y modificar su precio.

Figura A.18: Pagina Principal del Administrador

Aquı en la pagina principal se le muestran al administrador las distintas operaciones que

puede realizar en un panel lateral izquierdo, ordenadas por categorıas. Estas categorıas

son: ’Personal’, ’Ofertas’ y ’Habitaciones’.

’Personal’ contiene las siguientes operaciones: ’Actualizar info. registro’ y ’Salir’. Las

operaciones de esta categorıa son las mismas que se le proporcionan a un usuario normal,

por lo que se pueden ver en la pagina 225. En la categorıa de ’Ofertas’ se tienen operaciones

que permiten ’Crear Ofertas’ y ’Ver Ofertas’. En la tercera categorıa, ’Habitaciones’, se

le proporcionan las siguientes opciones: ’Nueva Habitacion’, ’Ver Habitaciones’ y ’Anadir

Incidencia’.

Page 272: Xesthproyecto

A.4. Manual Especıfico para el Administrador 240

A continuacion se explican cada una de las operaciones por separado:

Crear Ofertas

Esta operacion presenta un formulario como el de la figura A.19 en el cual el ad-

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: Pagina para Crear una Nueva Oferta

Page 273: Xesthproyecto

A.4. Manual Especıfico para el Administrador 241

Figura A.20: Pagina para Crear una Nueva Oferta (Rellenada)

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 habra que anadirlo pinchando sobre el enlace ’Nuevo Tipo de

Oferta’ como se explicara mas adelante.

Luego se cubriran las fechas de inicio de aplicacion y de fin, el descuento que se

quiere que proporcione la oferta y la regla que tiene que definir cuando se pue-

de aplicar la oferta. Para definir la regla se utiliza la nomenclatura ’NombreRe-

gla1:Argumento1 &&NombreRegla2:Argumento1,[...],ArgumentoN &&[...] &&Nom-

breReglaN:Argumento1,Argumento2’ pero sin ningun tipo de espacios. A continua-

cion se detallan los Nombre de Regla disponibles y sus argumentos necesarios:

• PersonBornBefore:(Dıa),(Mes),(Ano) Esta regla sirve para definir que se

le aplique la oferta a las personas que hayan nacido antes de la fecha indi-

cada.

◦ (Dıa): Numero entero especificando el dıa.

◦ (Mes): Numero entero especificando el mes.

Page 274: Xesthproyecto

A.4. Manual Especıfico para el Administrador 242

◦ (Ano): Numero entero especificando el ano.

• PersonBornAfter:(Dıa),(Mes),(Ano) Esta regla sirve para definir que se

le aplique la oferta a las personas que hayan nacido despues de la fecha

indicada.

◦ (Dıa): Numero entero especificando el dıa.

◦ (Mes): Numero entero especificando el mes.

◦ (Ano): Numero entero especificando el ano.

• PersonFrom:(Paıs) Esta regla sirve para definir que se le aplique la oferta a

las personas de cierto Paıs

◦ (Paıs): Nombre del paıs.

• ReservationDoneBefore:(Dıa),(Mes),(Ano) Esta regla sirve para definir

que se le aplique la oferta a los clientes que realicen la reserva (que la

paguen) antes de la fecha indicada.

◦ (Dıa): Numero entero especificando el dıa.

◦ (Mes): Numero entero especificando el mes.

◦ (Ano): Numero entero especificando el ano.

• 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 nue-

vo 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 operacion se le muestra al ad-

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 sera creado de verdad cuando se cree la nueva oferta que lo

utilice.

En este formulario se deben cumplimentar: el nombre del nuevo tipo de oferta y una

descripcion de este. Ademas se mostraran una lista de posibles productos a los que

Page 275: Xesthproyecto

A.4. Manual Especıfico para el Administrador 243

Figura A.21: Pagina para Crear un Nuevo Tipo de Oferta

podra ser aplicable la oferta de los cuales se eligiran los que se deseen, indicando a

su vez la cantidad mınima que se debe ordenar para que se aplique la oferta. Por

otro lado apareceran tambien todos los tipos de oferta que haya hasta el momento

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 esta creando.

Ver Ofertas

Esta operacion permite al administrador ver las ofertas que existen actualmente en el

sistema, la publicadas, las que no lo estan y los borradores. Las ofertas se mostraran

en una lista como la que se muestra en la figura A.22 y desde la cual se podra acceder

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 mostrara un formulario como el de la figura A.23

indicando las operaciones que podemos realizar con ella. Si la reserva aun esta mar-

cada como borrador se podran modificar sus datos, borrarla o publicarla, pero si ya

no es borrador solo se podra publicar en caso de que aun no lo este y ’despublicar’

Page 276: Xesthproyecto

A.4. Manual Especıfico para el Administrador 244

Figura A.22: Pagina para Listar las Ofertas

si ya habıa sido publicada. Se le ofrece este mecanismo al administrador por si por

error publica una oferta que no deberıa.

Figura A.23: Pagina para Realizar Operaciones con las Ofertas

Page 277: Xesthproyecto

A.4. Manual Especıfico para el Administrador 245

Ademas de proporcionar la opcion de consultar los datos de una oferta y modificarlos

tambien se le permite al administrador consultar y modificar los datos de un tipo de

oferta a traves del formulario que se muestra en la figura A.24. Para ello simplemente

debe hacer clic en el nombre del tipo de oferta que aparece en la lista de ofertas en

la columna correspondiente.

Figura A.24: Pagina para Realizar Operaciones con los Tipos de Ofertas

Nueva Habitacion

Esta operacion permite al administrador dar de alta una nueva habitacion en el

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

habitacion se muestra al administrador un formulario como el de la figura A.25 donde

debera especificar el numero que tendra la habitacion, el piso en el que estara la

habitacion y el precio extra que puede tener esta a mayores del precio que establezca

el tipo de habitacion.

Page 278: Xesthproyecto

A.4. Manual Especıfico para el Administrador 246

Figura A.25: Pagina para Dar de Alta una Habitacion

El tipo al que pertenecera, lo puede elegir de la lista, pero si no esta el deseado

debera crear uno que se ajuste a lo que necesia haciendo clic en ’Nuevo Tipo de

Habitacion’. Esta operacion de nuevo tipo, le permite al administrador crear un

nuevo tipo de habitacion a traves de un formulario como el que se muestra en la

figura A.26 donde debe especificar una breve descripcion, el numero de personas al

que esta destinado y el precio base que costara.

Figura A.26: Pagina para Crear un Nuevo Tipo de Habitacion

Page 279: Xesthproyecto

A.4. Manual Especıfico para el Administrador 247

Ver Habitaciones

Esta operacion permite al administrador ver las habitaciones que estan dadas de alta

actualmente en el sistema. Las habitaciones se mostraran en una lista como la que

se muestra en la figura A.27 y desde la cual se podra acceder para ver los datos de

una oferta en particular o un tipo de oferta.

Figura A.27: Pagina para Listar las Habitaciones para el Administrador

Para consultar los datos especıficos de una habitacion el administrador tiene que

hacer clic en ’Habitacion numero n’ y esto le mostrara un formulario como el de la

figura A.28 mediante el cual podra consultar los datos de la habitacion deseada o

modificarlos si lo desea.

Page 280: Xesthproyecto

A.4. Manual Especıfico para el Administrador 248

Figura A.28: Pagina para Consultar/Modificar los Datos de una Habitacion

Ademas se proporciona la opcion de consultar yo modificar los datos de un tipo

de habitacon a traves del formulario que se muestra en la figura A.29. Para ello

simplemente debe hacer clic en el nombre del tipo de habitacion que aparece en la

lista de habitaciones en la columna correspondiente.

Figura A.29: Pagina para Consultar/Modificar los Datos de un Tipo de Habitacion

Page 281: Xesthproyecto

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 ad-

ministrador pueda ver las incidencias de esa habitacion simplemente pinchando en

el. Al realizarlo se le muestra una lista con todas las incidencias registradas en esa

habitacion como se puede observar en la figura A.30.

Figura A.30: Pagina para Listar las Incidencias de una Habitacion

Anadir Incidencia

Esta operacion permite al administrador registrar una incidencia ocurrida en una

habitacion. Para realizar este cometido se le presenta un formulario como el de la

figura A.31 donde el administrador debe cubrir lo siguiente: elegir la habitacion

a la que esta relacionada la incidencia, definir el tipo de gravedad de la incidencia

(meramente informativo, a definir por el administrador), y una descripcion completa

de lo ocurrido.

Page 282: Xesthproyecto

A.4. Manual Especıfico para el Administrador 250

Figura A.31: Pagina para Registrar una Incidencia de una Habitacion

Page 283: Xesthproyecto

Apendice B

Licencia del Proyecto - GPLv31

A continuacion se muestra el contenido de esta licencia, aunque por motivos de validez

legal se provee en ingles, se puede consultar una version traducida en el siguiente enlace:

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

1General Public License version 3

251

Page 284: Xesthproyecto

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 copy-

right 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 incom-

patible 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 pre-

cisely 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.

Page 285: Xesthproyecto

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,

Page 286: Xesthproyecto

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 au-

tomatically 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.

Page 287: Xesthproyecto

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 circumven-

tion 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

Page 288: Xesthproyecto

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

Page 289: Xesthproyecto

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, aut-

horization 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

Page 290: Xesthproyecto

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 attribu-

tions 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

Page 291: Xesthproyecto

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 anyo-

ne who conveys the material (or modified versions of it) with contractual as-

sumptions 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.

Page 292: Xesthproyecto

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 accep-

tance. 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 organiza-

tions. 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”.

Page 293: Xesthproyecto

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 Co-

rresponding 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 pa-

tent 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 li-

cense, 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

Page 294: Xesthproyecto

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 otherwi-

se) 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 simul-

taneously 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.

Page 295: Xesthproyecto

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 PER-

MITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN

WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVI-

DE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER

EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IM-

PLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PAR-

TICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PER-

FORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM

PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SER-

VICING, 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 ABO-

VE, 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 POSSIBI-

LITY 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

Page 296: Xesthproyecto

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.

Page 297: Xesthproyecto

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 diffe-

rent; 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.

Page 298: Xesthproyecto
Page 299: Xesthproyecto

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. Matematica discreta y sus aplicaciones. ISBN 84-481-4073-7.

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

Page 300: Xesthproyecto

Bibliografıa 268

[10] Bernardo Cascales Salinas; Pascual Lucas Saorın; Jose Manuel Mira Ros; Antonio

Jose Pallares Ruiz y Salvador Sanchez-Pedreno Gillen. El libro de LATEX. ISBN

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 Do-

miney. CSS: Hojas de estilo en cascada para el diseno Web. ISBN 84-415-1954-4.

ANAYA, 2005.