scieee AI-readable full text Open interactive document viewer

Repositorio Institucional de Documentos

Abstract

Las posibilidades de acceso a la información que ofrecen las tecnologías actuales (internet, telefonía móvil…) ha propiciado que un gran número de empresas, particulares e instituciones, intenten ofrecer sus productos y servicios a todos sus potenciales consumidores de forma atractiva y eficaz, utilizando estas tecnologías. Esto ha hecho que hayan aparecido en el mercado diferentes “sistemas de ofertas”, como Groupon, Oooferton, Ofertix o Menus.es, dedicados a promocionar y mejorar las ventas de las empresas/negocios adheridos a dichos sistemas. No obstante, para muchos pequeños comercios, el coste que representa adherirse a uno de estos sistemas puede resultar demasiado elevado (bien sea porcentaje sobre cada venta, precio por publicación, etc.). Por todos estos motivos surgió la idea de este proyecto, como solución a un problema real, en el que un Ayuntamiento necesita disponer de un sitio web con un sistema de ofertas, que permita a sus comerciantes ofertar sus productos y servicios de una manera económica, y que además cuente con un apartado para que el propio Ayuntamiento pueda publicar eventos de interés público, como inauguraciones, cortes en carreteras, etc. Así, los ciudadanos de dicha localidad y su entorno tendrán la posibilidad, bien desde su casa o un teléfono móvil, de realizar sus compras y estar informados de los eventos de interés programados. Por tanto, el objetivo de este proyecto es diseñar y desarrollar un sitio web que permita la compra-venta de productos y servicios, así como la visualización de eventos y noticias de interés, de las empresas e instituciones que pertenezcan al entorno del Ayuntamiento. Para completar la aplicación, se dispondrá de un apartado con interfaz separada que implemente un sistema de ofertas que permita que cualquier empresa particular o institución, a nivel nacional, una vez dado de alta en el sistema, y con un coste reducido, pueda ofertar sus productos, servicios y eventos para que el consumidor pueda informarse o comprar, desde internet o desde un teléfono móvil. Es en este apartado donde las empresas e instituciones del entorno del ayuntamiento podran gestionar sus ofertas y eventos. Por otra parte, se intentará diseñar un producto lo más genérico posible, de modo que pueda ser utilizado, con un coste de adaptación reducido, para dar soporte a otra empresa/entidad. El primer paso consistirá, además de la planificación del desarrollo del proyecto, en el análisis de requisitos y la elaboración de las especificaciones de detalle, en base a las necesidades del cliente y de los usuarios. Esto incluirá una comparación de los sistemas de ofertas más relevantes que hay en el mercado, para extraer ideas y elaborar un proyecto competitivo. También se realizará un análisis de las diferentes tecnologías existentes que podrían utilizarse, atendiendo a criterios de coste, tiempo y facilidad de aprendizaje. Una vez establecidos los requisitos del proyecto se iniciará el diseño del sistema, prestando especial atención al diseño de las interfaces de usuario para navegador y para móvil, y de la base de datos y estructuras de información necesarias. Tras la implementación, utilizando las herramientas y lenguajes seleccionados, se comprobará el correcto funcionamiento del sistema y el cumplimiento de los requerimientos previamente establecidos. Fuertes Pueyo, Daniel; Carro Mariño, Antonio

Full text

Proyecto Final de Carrera Ingeniería Informática Curso 2011-2012 Análisis y desarrollo de una aplicación web para la publicación y venta de productos. Memoria Daniel Fuertes Pueyo Junio de 2012 Director: Antonio Carro Mariño Responsable de estrategia e innovación Sdweb Soluciones Digitales Ponente: Santiago Velilla Marco Departamento de Informática e Ingeniería de Sistemas Escuela de Ingeniería y Arquitectura Universidad de Zaragoza 2 Índice 1 Introducción................................................................................................................................................5 1.1 Contexto....................................................................................................................................5 1.2 Objetivos y alcance del proyecto..............................................................................................5 1.3 ¿A quien va dirigido?................................................................................................................6 1.4 Ciclo de vida.............................................................................................................................6 1.5 Planificación.............................................................................................................................7 1.6 Organización de este documento..............................................................................................7 2 Investigación Preliminar............................................................................................................................8 2.1 Comparación de los sistemas de ofertas más relevantes...........................................................8 2.2 Análisis de tecnologías............................................................................................................10 2.2.1 Framework RIA: Vaadin.................................................................................................10 2.2.2 Framework ORM: ORMLite vs Hibernate.....................................................................11 2.2.3 Base de datos: PostgreSQL vs MySQL...........................................................................11 3 Requisitos .................................................................................................................................................13 3.1 Requisitos funcionales............................................................................................................13 3.2 Requisitos no funcionales.......................................................................................................16 4 Análisis y diseño del sistema.....................................................................................................................17 4.1 Análisis del sistema.................................................................................................................18 4.1.1 Casos de uso....................................................................................................................18 4.1.2 Diseño de interfaces........................................................................................................22 4.1.3 Diagramas de secuencia..................................................................................................25 4.2 Diseño del sistema..................................................................................................................26 4.2.1 Diagrama de clases..........................................................................................................27 4.2.2 Diseño de la base de datos .............................................................................................34 5 Implementación........................................................................................................................................35 5.1 Acceso de un usuario..............................................................................................................35 5.2 Cambio de idioma...................................................................................................................39 5.3 Geolocalización......................................................................................................................40 6 Pruebas del sistema...................................................................................................................................42 7 Conclusiones y lineas futuras...................................................................................................................45 7.1 Conclusiones...........................................................................................................................45 7.2 Lineas futuras..........................................................................................................................46 8 bibliografía................................................................................................................................................46 3 Índice de tablas Tabla 1: central de ofertas vs sistemas de compra directa..................................................................12 Tabla 2: Plantilla para definir casos de uso........................................................................................24 Tabla 3: Ejemplo de casos de uso.......................................................................................................25 Tabla 4: Plantilla para definir un caso de prueba................................................................................45 Tabla 5: ejemplo de caso de prueba....................................................................................................48 Índice de ilustraciones Ilustración 1: ciclo de vida en cascada.................................................................................................9 Ilustración 2: Planificación.................................................................................................................10 Ilustración 3: Diagrama de casos de uso de una institución...............................................................22 Ilustración 4: Diagrama de casos de uso de un usuario......................................................................22 Ilustración 5: Diagrama de casos de uso de un usuario no registrado................................................23 Ilustración 6: Diagrama de casos de uso de una empresa...................................................................23 Ilustración 7: Diagrama de casos de uso de un administrador...........................................................24 Ilustración 8: Pantalla principal..........................................................................................................26 Ilustración 9: Pantalla principal para usuarios....................................................................................26 Ilustración 10: Error en formulario.....................................................................................................27 Ilustración 11: Error en base de datos.................................................................................................27 Ilustración 12: Esquema de un diagrama de secuencia......................................................................28 Ilustración 13: diagrama de secuencia del CU-2 identificarse...........................................................29 Ilustración 14: Esquema de definición una clase en un diagrama de clases.......................................30 Ilustración 15: Relación entre las clases que componen el paquete modelo......................................30 Ilustración 16: Definición de las clases del paquete modelo..............................................................31 Ilustración 17: Clases del paquete vista web para un administrador..................................................32 Ilustración 18: Clases del paquete vista web para un usuario............................................................32 Ilustración 19: Clases del paquete vista web para una institución ....................................................33 Ilustración 20: Clases del paquete vista web para un usuario no registrado......................................33 Ilustración 21: Clases del paquete vista web para una empresa.........................................................34 Ilustración 22: Clases del paquete vista móvil para un usuario no registrado....................................34 Ilustración 23: Clases del paquete vista móvil para un usuario..........................................................35 Ilustración 24: Clases del paquete vista widget para un usuario no registrado..................................35 Ilustración 25: Clases del paquete vista widget para un usuario........................................................36 Ilustración 26: Diagrama de clases de la aplicación web...................................................................36 Ilustración 27: Diagrama de clases de la aplicación móvil................................................................36 Ilustración 28: Diagrama de clases de la aplicación widget...............................................................37 Ilustración 29: Diagrama entidad-relación.........................................................................................37 Ilustración 30: Diagrama de casos de uso de un usuario no registrado..............................................52 Ilustración 31: Diagrama de casos de uso de un usuario....................................................................53 Ilustración 32: Diagrama de casos de uso de una empresa.................................................................54 Ilustración 33: Diagrama de casos de uso de una institución.............................................................54 Ilustración 34: Diagrama de casos de uso de un administrador.........................................................55 4 1 INTRODUCCIÓN El objetivo de esta memoria es explicar del modo mas simple y claro posible el objeto del proyecto y los aspectos mas relevantes de su diseño, implementación y prueba. Este capítulo pretende introducir al lector en el dominio del sistema desarrollado. Se presentará el contexto en el que ha sido desarrollado, además de enumerar los objetivos del proyecto y las tareas realizadas dentro del mismo. 1.1 Contexto Este proyecto ha sido desarrollado en la empresa Sdweb Soluciones Digitales. Sdweb es una pequeña empresa en crecimiento situada en la ciudad de Santiago de Compostela. Trabaja sobre todo con las instituciones (ayuntamientos, universidades,…) de la zona de Galicia, aunque también tiene proyectos en Cataluña. Se dedica a tres campos principalmente: •Comunicación digital: proyectos adaptados a necesidades concretas, optimización de entornos y desarrollo de estrategias de comunicación con el fin de aumentar su visibilidad. •E-learning: social learning y potenciación de la comunicación y colaboración en el seno de las organizaciones. •Gestión documental: Desarrollo e implementación de sistemas de gestión documental y bases de datos para garantizar la calidad en la gestión de la información. Las posibilidades de acceso a la información que ofrecen las tecnologías actuales (internet, telefonía móvil…) ha propiciado que un gran número de empresas, particulares e instituciones, intenten ofrecer sus productos y servicios a todos sus potenciales consumidores de forma atractiva y eficaz, utilizando estas tecnologías. Esto ha hecho que hayan aparecido en el mercado diferentes “sistemas de ofertas”, como Groupon, Oooferton, Ofertix o Menus.es, dedicados a promocionar y mejorar las ventas de las empresas/negocios adheridos a dichos sistemas. No obstante, para muchos pequeños comercios, el coste que representa adherirse a uno de estos sistemas puede resultar demasiado elevado (bien sea porcentaje sobre cada venta, precio por publicación, etc.). Por todos estos motivos surgió la idea de este proyecto, como solución a un problema real, en el que un Ayuntamiento pidió a Sdweb una central de ofertas que permitiera a sus comerciantes ofertar sus productos y servicios de una manera económica, y que además contara con un apartado para que las instituciones del Ayuntamiento puedan publicar eventos de interés público, como inauguraciones, cortes en carreteras, etc. Así, los ciudadanos de dicha localidad y su entorno tendrán la posibilidad, bien desde su casa o un teléfono móvil, de realizar sus compras y estar informados de los eventos de interés programados. 1.2 Objetivos y alcance del proyecto El objetivo de este proyecto es diseñar y desarrollar un sitio web que permita la compraventa de productos y servicios, así como la visualización de eventos y noticias de interés de las empresas e instituciones que pertenezcan al entorno del Ayuntamiento. Para completar la aplicación, se dispondrá de un apartado, con interfaz separada, que implemente un sistema de ofertas que permita que cualquier empresa particular o institución, a nivel nacional y una vez dado de alta en el sistema, pueda ofertar sus productos con un coste reducido, servicios y eventos de modo que cualquier potencial consumidor pueda informarse o comprar, desde internet o desde un teléfono móvil. Es en este apartado donde las empresas e instituciones del entorno del ayuntamiento podrán gestionar sus ofertas y eventos. Por otra parte, se intentará diseñar un producto lo más genérico posible, de modo que pueda ser utilizado, con un coste de adaptación reducido, para dar soporte a otra empresa/entidad. El sitio web estará alojado en un servidor de Sdweb y sera administrado por ésta. 5 1.3 ¿A quien va dirigido? La central de ofertas no está acotada a ningún sector en concreto y su ámbito (idiomas) de implantación sería el nacional (español, gallego) aunque el sistema desarrollado estará implementado de tal manera que se sea fácilmente traducible a cualquier otro idioma. •Empresa pequeña – mediana que no cuenta con un portal web y sólo desea publicar información. •Empresa pequeña – mediana que tiene un portal web y desea compaginarlo con una aplicación móvil. •Empresa de nueva creación que desee contar con un sistema que le permita fácilmente incorporar ofertas y publicarlas en un canal de ofertas común •Asociaciones de todo tipo •Centros comerciales, mercados, centros de negocio… •Administraciones locales para potenciar la industria turística, gastronómica, termal, ofrecer información sobre lo que sucede en un lugar concreto •Promotores inmobiliarios •Empresa pequeña – media – grande que necesite realizar una campaña de marketing a través de internet para dar a conocer sus productos o servicios en detalle y articular fórmulas para contactar con los clientes. 1.4 Ciclo de vida El primer paso consistirá, además de la planificación del desarrollo del proyecto, en el análisis de requisitos y la elaboración de las especificaciones de detalle, en base a las necesidades del cliente y de los usuarios. Esto incluirá una comparación de los sistemas de ofertas más relevantes que hay en el mercado para extraer ideas y elaborar un proyecto competitivo. También se realizará un análisis de las diferentes tecnologías existentes que podrían utilizarse, atendiendo a criterios de coste, tiempo y facilidad de aprendizaje. Una vez establecidos los requisitos del proyecto se iniciará el diseño del sistema, prestando especial atención al diseño de las interfaces de usuario para navegador y para móvil, y de la base de datos y estructuras de información necesarias. Tras la implementación, utilizando las herramientas y lenguajes seleccionados, se comprobará el correcto funcionamiento del sistema y el cumplimiento de los requerimientos previamente establecidos. El ciclo de vida seleccionado para el desarrollo del sistema ha sido el ciclo de vida en cascada mejorado. 6 Ilustración 1: ciclo de vida en cascada Es un ciclo de vida que admite iteraciones, contrariamente a la creencia de que es un ciclo de vida secuencial o lineal. Después de cada etapa se realiza una o varias revisiones para comprobar si se puede pasar a la siguiente. Aun asi, es un modelo rígido, poco flexible y con muchas restricciones. Una de sus ventajas, ademas de su planificación sencilla, es la de proporcionar un producto final con un elevado grado de calidad, sin necesidad de un personal altamente cualificado. Se puede considerar como inconvenientes la necesidad de contar con todos los requerimientos (o la mayoría) al comienzo del proyecto y que, si se han cometido errores y no se detectan en la etapa siguiente, es costoso y complejo volver atrás para realizar la corrección del error. Además, los resultados no los veremos hasta que no estemos en las etapas finales del ciclo, por lo que cualquier error detectado genera un retraso y aumenta el costo del desarrollo de forma proporcional al tiempo que empleado en la corrección de dichos errores. Es un ciclo de vida adecuado para los proyectos en los que se dispone de todos los requerimientos al comienzo, para el desarrollo de un producto con funcionalidades conocidas o para proyectos que, aun siendo muy complejos, se entienden perfectamente desde el principio. Se ha elegido este ciclo de vida porque desde el inicio se dispone de todos los requerimientos y se conocen sus funcionalidades. Además, el Ayuntamiento no tiene prisa por ver el resultado, ya que en el momento del desarrollo del proyecto no tenía presupuesto para pagarlo. El motivo por el que se ha implementado este sistema es que Sdweb ha visto una oportunidad de negocio en este proyecto, ya que el sistema de ofertas nacional será administrado por Sdweb y el sistema de ofertas especifico de un ayuntamiento, al ser genérico, podría ser vendido a otro ayuntamiento. 1.5 Planificación En este apartado se va a explicar la planificación de tareas que se ha seguido durante el proyecto. Para ello, se expone un diagrama de Grantt que ilustra la realización de las diferentes fases que componen el proyecto. Para comenzar se hizo una estimación del coste en tiempo de la fase de análisis y diseño. Una vez realizada esta fase, se pudo completar el diagrama de Grantt con las siguientes fases del proyecto. 1.6 Organización de este documento. El presente documento está dividido en dos partes: Memoria, donde se explica el desarrollo del proyecto, y Anexos, donde se amplía la información de ciertos puntos relevantes. En el siguiente capítulo se realiza una investigación preliminar sobre los diferentes sistemas de ofertas que existen en el mercado y sobre las tecnológias que se van a utilizar. Además se realiza 7 Ilustración 2: Planificación un estudio sobre el tipo de consumidor al que le podría interesar el producto desarrollado. Posteriormente se muestran los requisitos funcionales y no funcionales del sistema extraídos de la investigación preliminar. Una vez presentados los requisitos, se realiza el análisis y el diseño del sistema. En este capitulo se pretende definir de forma clara y precisa lo que desea el usuario y la forma en la cual se va a presentar la solución que se está buscando y se define una subdivisión en aplicaciones del sistema. Tras el diseño, se presentan los aspectos de la implementación más importantes y que como desarrollador han supuesto un mayor desafío o han resultado más llamativos o novedosos. Después de haber explicado la implementación, se describen las pruebas realizadas para comprobar el cumplimiento de los requerimientos. En el ultimo capítulo se exponen las conclusiones y las líneas futuras de desarrollo. 2 INVESTIGACIÓN PRELIMINAR 2.1 Comparación de los sistemas de ofertas más relevantes El primer paso antes de abordar el diseño de un sistema suele consistir en la evaluación critica y estudio comparativo de los sistemas más relevantes similares al que se va a desarrollar. En este apartado se va a realizar un estudio de los aspectos generales de los sistemas de ofertas mas relevantes para extraer ideas, no sólo acerca de aspectos funcionales, estéticos y de interfaz, sino también de herramientas, con objeto de elaborar un proyecto competitivo. Las webs que ofrecen productos y servicios a precios rebajados o con descuento han inundado el mercado actual, quizás debido a la crisis que nos acompaña desde hace tiempo. Son una buena oportunidad para comprar dichos productos y servicios con descuento de manera cómoda y sencilla desde nuestros hogares, pero adolecen todavía de algunos inconvenientes que deberemos tener en cuenta. Existen dos tipos claramente diferenciados, las webs de compra directa y las de compra colectiva. Las webs de compra directa, son clubs de venta privada online que ofrecen artículos rebajados o con descuento. Su ámbito es local y se encargan de enviar por correo al domicilio del comprador dichas ofertas. Algunos también venden servicios (como estancias en hoteles o viajes). Las páginas mas conocidas son Privalia, ofertix y BuyVip. Por otro lado, las webs de compra colectiva son intermediarios que venden cupones canjeables por servicios en otras empresas y sus ofertas cambian en función del número de personas que se apunte a ellas. Normalmente requieren de un número mínimo de personas “apuntadas” a las ofertas para que éstas se materialicen. Las páginas mas conocidas son Groupon, LetsBonus y Planeo. Como resumen de las características básicas de los sistemas de ofertas que hay en el mercado, en la tabla que se presenta a continuación se muestran dichas características, junto con las que dispondrá el sistema de central de ofertas a desarrollar. Características Central de ofertas compras colectivas Compras directas Empresa La empresa puede publicar sus ofertas a través del portal. Sí Sí Sí Las ventas de ofertas se realizan a través del portal. Sí Sí Sí 8 Características Central de ofertas compras colectivas Compras directas Importes de ventas recibidos por el portal van directamente a la cuenta de la Empresa. Sí No No Gestión de ofertas de forma autónoma por la empresa. Sí No No Comisión a pagar por venta 10% 50% No Precio por publicación No No Sí Ver ventas realizadas Sí Sí Sí Ver compras realizadas Sí No No Ver ofertas publicadas Sí Sí Sí Entrega a domicilio No No Algunas Institución La institución puede publicar sus eventos a través del portal Sí No No Gestión de eventos de forma autónoma por la empresa. Sí No No Ver eventos publicados Sí No No Modificar datos Sí No No Usuario Ofertas del día Sí Sí Sí ¿Que hay a mi alrededor? Sí Sí Sí Guía de mi ciudad Sí No No Buscar reservas Sí No No Añadir oferta a favoritos Sí No No Guardar búsqueda Sí No No Ver compras realizadas Sí Sí Sí Modificar datos Sí Sí Sí Tabla 1: central de ofertas vs sistemas de compra directa Mientras que las web de compra directa están enfocadas a la publicidad de las empresas para darlas a conocer, obteniendo un alto porcentaje por cada venta, la central de ofertas está más enfocada a vender productos y servicios a partir de un método de publicación de ofertas más barato y menos controlado que los otros dos. Además, el sistema desarrollado ofrece al consumidor más opciones a la hora de la buscar ofertas, ya que cuenta con un buscador de ofertas, mientras que en los otros dos sólo puedes ver las ofertas del día de una localidad. El sistema desarrollado también cuenta con un apartado para instituciones donde pueden gestionar sus eventos de manera gratuita. 9 avisándole. RF-57: Buscar/eliminar empresas que hagan uso indebido de la aplicación. RF-58: Listar ofertas de una empresa RF-59: Listar ventas de una empresa RF-60: Calcular un porcentaje sobre los ingresos que ha recibido una empresa en un determinado mes. RF-61: Aceptar/denegar peticiones de nuevas instituciones RF-62: Una vez aceptada una petición se le enviara un correo electrónico a la institución avisándole. RF-63: Buscar/eliminar instituciones que hagan uso indebido de la aplicación. RF-64: Listar eventos de una institución RF-65: Buscar/eliminar usuarios que hagan uso indebido de de la aplicación RF-66: Listar compras de un usuario RF-67: Buscar/eliminar reservas RF-68: Buscar/eliminar eventos Requisitos sobre validación de datos. RF-69: No podrán registrarse dos usuarios de cualquier tipo con la misma dirección de correo electrónico (aunque sean distinto tipo de usuario). RF-70: No podrán registrarse dos empresas con el mismo nombre. RF-71: No podrán registrarse dos instituciones con el mismo nombre. RF-72: Ningún tipo de usuario podrá registrarse con el mismo nombre que el administrador. RF-73: Todos los campos de registro deberán ser obligatorios. RF-74: Una dirección de correo electrónico deberá tener el siguiente formato: buzon@subdominio. ... .subdominio2.subdominio1.dominio-de-mas-alto-nivel RF-75: EL teléfono, el código postal, el numero de cuenta, el portal, el piso, el precio, el iva y el stock inicial deberán ser un número. Además la central de ofertas dispondrá de un apartado, con interfaz separada, para integrarse en un sitio web que permita la compra-venta de productos y servicios y la visualización de eventos y noticias de interés de las empresas e instituciones que pertenezcan al entorno de un Ayuntamiento específico. Este apartado podrá utilizarse sin identificarse en el sistema, solo en caso de querer comprar alguna reserva habrá que realizar el acceso. En este apartado un usuario podrá: RF-76: buscar reservas del día de una zona RF-77: buscar eventos de una zona RF-78: buscar reservas por diferentes criterios(empresa, descripción, sector, etiquetas) RF-79: Buscar empresas de la zona RF-80: buscar reservas del día de una empresa de la zona RF-81: buscar reservas de una empresa de una zona por diferentes criterios(empresa, descripción, sector, etiquetas) y los requisitos RF-25, RF-33, RF-34, RF-35, RF-36, RF-37, RF-38, RF-39, RF-40. 3.2 Requisitos no funcionales RNF-1: Garantizar la confiabilidad, la seguridad y el desempeño del sistema informático a los diferentes usuarios a nivel nacional. En este sentido la información almacenada podrá ser consultada y actualizada permanente y simultáneamente, sin que se afecte el tiempo de respuesta. RNF-2: El sistema debe tener capacidad para dar respuesta al acceso simultaneo de todos los usuarios con tiempo de respuesta aceptable y uniforme en períodos de alta, media y baja 16 demanda de uso del sistema. RNF-3: El sistema debe estar implementado de tal manera que la incorporación de nuevas funcionalidades y requerimientos pueda realizarse de modo que que el código existente se vea afectado de forma mínima. RNF-4: El sistema debe ser de fácil uso por parte de los usuarios. RNF-5: El sistema debe presentar mensajes de error que permitan al usuario identificar el tipo de error y comunicarse con el administrador del sistema. RNF-6: El sistema debe contar con facilidades para la identificación de la localización de los errores durante la etapa de pruebas y de operación posterior. RNF-7: Todo el sistema deberá estar complemente documentado y, en concreto, cada uno de los componentes de software que forman parte de la solución propuesta, tanto en el código fuente como en los manuales de administración y de usuario. RNF-8: El acceso al Sistema debe estar restringido por el uso de claves asignadas a cada uno de los usuarios. Sólo podrán ingresar al Sistema las personas que estén registradas. Los usuarios serán clasificados en varios tipos de usuarios (o roles) con acceso a las opciones de trabajo definidas para cada rol. RNF-9: El control de acceso implementado debe permitir asignar los perfiles para cada uno de los roles identificados. RNF-10: El sistema debe validar automáticamente la información contenida en los formularios de ingreso. En el proceso de validación de la información, se deben tener en cuenta aspectos tales como obligatoriedad de campos, longitud de caracteres permitida por campo, manejo de tipos de datos, etc. RNF-11: La solución debe ser 100% Web y todas las operaciones deben realizarse desde un navegador. RNF-12: La solución debe operar de manera independiente del navegador que se utilice. RNF-13: La solución debe tener interfaces gráficas de administración y de operación en idioma español y gallego. RNF-14: La aplicación móvil detectará automáticamente la provincia en la que se encuentra el usuario. RNF-15: Los backup´s deben ser responsabilidad del administrador del sistema quien deberá crearlos, almacenarlos y recuperar la información en el caso que se pierda información. Se deberá realizar una copia diaria de la información y borrar las copias que excedan de una semana. RNF-16: La LOPD dice que en los sitos web con operación monetarias hay que guardar los datos de los usuarios por lo menos durante 4 años. Por lo que las empresa, usuarios y ofertas que sean borradas, ya sea por cuenta propia o del administrador, deberán ser guardadas en la base de datos durante, al menos, 4 años. 4 ANÁLISIS Y DISEÑO DEL SISTEMA Para realizar el análisis se ha utilizado el Análisis Orientado a Objetos (AOO) que se define como "un método de análisis que examina los requisitos desde la perspectiva de las clases y objetos que se encuentran en el vocabulario del dominio del problema". Los objetos son entidades tangibles que muestran un comportamiento bien definido. Se ha utilizado este tipo de análisis ya que el lenguaje seleccionado para la implementación del sistema es Java, que es un lenguaje orientado a objetos, y porque se ha considerado esta metodología como la más adecuada para este tipo de problema. Todo esto quiere decir que el análisis orientado a objetos parte de entidades tangibles halladas en el problema; Tales entidades varían dependiendo de los diversos casos prácticos, pero en todos los casos son elementos reales que toman parte del problema de forma directa. El Diseño Orientado a Objetos (DOO) "es el método que lleva a una descomposición Orientada a Objetos. Aplicando DOO, se crea software resistente al cambio. Se logra un mayor nivel de confianza en la corrección del software a través de la división inteligente de su espacio de estados. En última instancia, se reducen los riesgos inherentes al desarrollo de sistemas. 17 Los modelos del diseño orientado a objetos reflejan la importancia de plasmar explícitamente las jerarquías de clases y objetos del sistema que se diseña. Estos modelos cubren también el espectro de las decisiones de diseño relevantes que hay que considerar en el desarrollo de un sistema complejo, y así animan a construir implantaciones que posean los atributos de los sistemas complejos bien formados. Vamos a seleccionar un requisito del apartado anterior y vamos a seguir su evolución a través de todos las etapas siguientes para ilustrar la metodología de diseño empleada y su notación. El requisito elegido es el RF-25 Un usuario se identificará en el sistema mediante su dirección de correo electrónica y su clave. 4.1 Análisis del sistema En esta etapa se logra claridad sobre lo que desea el usuario y la forma en la cual se va a presentar la solución que se está buscando. Se examinan los requisitos desde la perspectiva de los objetos y clases del dominio del problema. 4.1.1 Casos de uso El modelo de casos de uso describe un sistema en base a sus distintas formas de utilización, cada una de las cuales es conocida como un caso de uso. Cada caso de uso o flujo se compone de una secuencia de eventos iniciada por el usuario. Dado que los casos de uso describen el sistema a desarrollar, cambios en los requisitos significarán cambios en los casos de uso. Los diagramas de casos de uso muestran las operaciones que puede realizar cada actor. Para ello se define el concepto de actor, correspondiente al tipo de usuario que está involucrado en la utilización de un sistema, siendo el actor una entidad externa al propio sistema. Los actores que participaran en el sistema son: Actor: S Sistema Descripción El sistema de ofertas Actor: ACT-1 Usuario No registrado Descripción Actor antes de acceder en la aplicación Actor: ACT-2 Usuario registrado Descripción Actor después de acceder como usuario Actor: ACT-3 Empresa registrada Descripción Actor después de acceder como empresa Actor: ACT-4 Institución registrada Descripción Actor después de acceder como institución Actor: ACT-5 Administrador Descripción Actor después de acceder como administrador Actor: ACT-6 Facebook 18 Descripción Red social externa Actor: ACT-7 Twitter Descripción Red social externa Actor: ACT-8 Google maps Descripción Gestor de mapas externo Tras haber definido los actores del sistema, se identifican los casos de uso del sistema a partir de los requisitos. Éstos junto con los actores representan los dos elementos básicos del diagrama de casos de uso. Para la mejor comprensión del diagrama de casos de uso, se ha diseñado un diagrama por cada actor del sistema. El diagrama de casos de uso del sistema es el siguiente: 19 Ilustración 3: Diagrama de casos de uso de una institución Ilustración 4: Diagrama de casos de uso de un usuario 20 Ilustración 5: Diagrama de casos de uso de un usuario no registrado Ilustración 6: Diagrama de casos de uso de una empresa Una vez que hemos identificado todos los casos de uso, hay que definirlos en alto nivel y para ello se ha utilizado la siguiente plantilla: Caso de Uso: CU-<Número Secuencia> Nombre Descripción <Breve descripción de la funcionalidad del caso de uso> Actores <Lista de actores que participan en la realización del caso de uso> Secuencia Normal <En este apartado se describe el escenario principal del caso de uso mediante una secuencia normal de pasos o acciones necesaria para cumplir con éxito la funcionalidad del caso de uso> Secuencia(s) Alternativas(s) <En este apartado se describen uno o más escenarios alternativos del caso de uso que representan situaciones distintas a la normal (p.e. ha ocurrido un error, y describe cómo tiene que responder el sistema ante tal situación)> Precondiciones <Condiciones que se deben cumplir antes de ejecutar el caso de uso> Postcondiciones <Condiciones que se deben cumplir al finalizar el caso de uso> Tabla 2: Plantilla para definir casos de uso 21 Ilustración 7: Diagrama de casos de uso de un administrador En el caso concreto del requisito RF-25 Un usuario se identificará en el sistema mediante su dirección de correo electrónica y su clave, buscamos en la matriz de trazabilidad casos de uso – requisitos del anexo A el caso de uso relacionado con el requisito y vemos que es CU-2 identificarfse. Caso de Uso: CU-2 Identificarse Descripción El actor puede identificarse sistema mediante su dirección de correo electrónico y su clave. Accederá al apartado gráfico correspondiente al tipo de usuario al que pertenezca. Actores S, ACT-1 Precondiciones El actor dispone de conexión a internet. El sistema funciona correctamente. El actor se encuentra en el sistema pero aun no ha accedido. El actor está registrado. El actor se encuentra en la página de acceso.(ilustración 8). Secuencia Normal 1. ACT: introduce su dirección de correo electrónico y su contraseña y le da “aceptar”. 2. S: Verifica en la base de datos que existe una cuenta de algún tipo de usuario con ese dirección de correo electrónico y esa contraseña y muestra la pantalla principal para ese tipo de usuario(ilustración 9). Secuencia(s) Alternativas(s) 2a. S: No existe el dirección de correo electrónico en la base de datos. Muestra un mensaje de error informando de que no existe la cuenta (ilustración 10). 2b. S: Contraseña errónea. Muestra un mensaje de error informando que la contraseña es errónea (ilustración 10). 2c. S:Falla al insertar en la base de datos. Muestra un mensaje informando de dicho error(ilustración 11). Postcondiciones El actor ha accedido al apartado gráfico del sistema correspondiente al tipo de usuario al que pertenece. El sistema no sufre incidencias y su funcionamiento es adecuado. Tabla 3: Ejemplo de casos de uso El resto de casos de uso se encuentra desarrollado en detalle en el anexo A. 4.1.2 Diseño de interfaces Dado que el modelo de casos de uso está motivado y enfocado principalmente hacia los sistemas de información donde los usuarios juegan un papel primordial, es importante ya relacionarse con las interfaces a ser diseñadas en el sistema. Estas interfaces sirven para apoyar de mejor manera la descripción de los casos de uso además de servir de base para prototipos iniciales. El modelo de interfaces describe la presentación de información entre los actores y el sistema. Se especifica en detalle como se verán las interfaces de usuario al ejecutar cada uno de los casos de uso. Para el diseño ha sido esencial que las interfaces reflejen la visión lógica del sistema ya que es uno de los principios fundamentales del diseño de interfaces humanas, donde debe existir consistencia entre la imagen conceptual del usuario y el comportamiento real del sistema. 22 Para diseñar el interfaz, se ha realizado un diseño de cada pantalla que debe presentar el sistema siguiendo la secuencia de pasos de cada caso de uso. Para el diseño de las pantallas se ha usado el programa Balsamiq. Como hemos visto en el apartado anterior, en CU-2 identificarse partimos de la pantalla principal (ilustración 8) y, siguiendo los la secuencia normal de pasos llegamos a la pantalla principal para usuarios ( ilustración 9). El diseño de estas pantallas es el siguiente: La Ilustración 8 muestra todas las funcionalidades que tiene un usuario que aun no ha accedido al sistema desde el apartado de internet y que no son una extensión de otra funcionalidad. Estas funcionalidades son cambiar el idioma, acceder, ofertas del día, ¿que hay a mi alrededor?, la guía de mi ciudad, buscar reservas, registrarse y conocer el funcionamiento del sistema. La Ilustración 9 muestra todas las funcionalidades que tiene un usuario que ha accedido como tipo de usuario usuario al sistema desde el apartado de internet y desde el apartado móvil que no son una extensión de otra funcionalidad. Estas funcionalidades son cambiar el idioma, salir, ofertas del día, ¿que hay a mi alrededor?, la guía de mi ciudad, buscar reservas, favoritos, mi cuenta y conocer el funcionamiento del sistema. 23 Ilustración 8: Pantalla principal Ilustración 9: Pantalla principal para usuarios Si ocurriera un error durante la secuencia normal, se mostrarían las pantallas de error (ilustración 10 y 11). El diseño de las pantallas de error es el siguiente: La Ilustración 10 muestra mensajes de error según los requisitos funcionales de validación de datos y los requisitos no funcionales RNF-5 y RNF-10. La Ilustración 11 muestra mensajes de error según el requisitos no funcional RNF-5. El resto de diseños de los interfaces se encuentran en el anexo B. 4.1.3 Diagramas de secuencia Para describir la información de entrada y salida de cada caso de uso se utilizan los diagramas de secuencia. Un diagrama de Secuencia muestra una interacción ordenada según la secuencia temporal de eventos. En particular, muestra los objetos participantes en la interacción y los mensajes que intercambian, ordenados según su secuencia en el tiempo. Un diagrama de secuencia muestra una interacción organizada basándose en los objetos que toman parte en la interacción y los enlaces entre los mismos. 24 Ilustración 10: Error en formulario Ilustración 11: Error en base de datos Vaadin implementa el patrón MVC (Modelo-Vista-Controlador), una arquitectura que busca reducir el acoplamiento, dividiendo las responsabilidades en 3 capas claramente diferenciadas: •El modelo, que a su vez está divido en dos capas: la capa que hace referencia a los datos que maneja la aplicación y la lógica de negocio que opera sobre ellos, y la capa de persistencia (DAO) que es la que interactúa con la base de datos. •La vista, encargada de generar la interfaz con la que la aplicación interacciona con el usuario. •El controlador, que comunica la vista y el modelo, respondiendo a eventos generados por el usuario en la vista, invocando cambios en el modelo, y devolviendo a la vista la información del modelo necesaria para que pueda generar la respuesta adecuada para el usuario. Para el diseño de los diagramas de secuencia se va a tener en cuenta esta arquitectura ya que presenta varias ventajas como la organización del código, la reutilización y la flexibilidad. Un diagrama de secuencia siguiendo esta arquitectura presenta el siguiente esquema. Para construir un Diagrama de Secuencia del Sistema para el curso típico de eventos de un caso de uso, se dibuja una línea para el actor que opera directamente con el sistema y otra para la clase controlador. En el diagrama anterior corresponderían con actor y controlador. Después, partiendo del texto del curso típico de eventos del caso de uso, las acciones realizadas por el actor hay que identificarlas como eventos (externos) del sistema y se representan en el diagrama como un mensaje desde el actor hacia el controlador. En el diagrama anterior corresponderían con los mensajes evento1 y evento2. Por otro lado, las acciones realizadas por el sistema pueden ser de dos tipos: mostrar una ventana o realizar una operación. Cuando una acción del sistema es del tipo mostrar una vista, se crea una clase vista que se añade al diagrama (en el diagrama anterior vista1) y se manda un mensaje de creación desde el controlador hasta la clase. En el diagrama anterior se correspondería con el mensaje llamada a vista 1. Si una acción del sistema es del tipo operación, entonces se añade al diagrama la clase relacionada con la operación (en el diagrama anterior lógica) y se añade al diagrama un mensaje desde el controlador hacia la clase con una llamada a una función de la clase. En el diagrama anterior se correspondería con el mensaje llamada a lógica de negocio. Si la operación tiene que usar la base de datos, se añade al diagrama la clase DAO y un mensaje desde el objeto relacionado con la operación hacia la clase DAO con una llamada a una función de la clase DAO. En el diagrama anterior se correspondería con el mensaje llamada a capa de persistencia. Por ejemplo, si una acción del sistema es “Buscar todas las empresas en la base de datos” se 25 Ilustración 12: Esquema de un diagrama de secuencia 32 Ilustración 23: Clases del paquete vista móvil para un usuario Ilustración 24: Clases del paquete vista widget para un usuario no registrado Las clases de un paquete de la vista no tienen relación entre ellas, ya que se comunican a través del controlador. Vaadin opera de tal manera que el paquete controlador sólo se compone de la clase controlador. Esta clase será la encargada de llamar a las clases de la vista que crean los interfaces y de capturar los eventos que éstos generan. Una vez capturado un evento, se llama a la operación de la clase del modelo que corresponda o a otro interfaz. Para definir el diagrama de clases de cada aplicación, se ha utilizado el mismo modelo para las tres aplicaciones, mientras que cada aplicación solo contiene las vistas que necesita y su propio controlador. La arquitectura de la aplicación web contiene el paquete modelo, el paquete controladorWEB, y los paquetes que contienen las vistas web. El diagrama de clases será el siguiente: La arquitectura de la aplicación móvil contiene el paquete modelo, el paquete controladorMOVIL, y los paquetes que contienen las vistas móvil. El diagrama de clases será el siguiente: 33 Ilustración 26: Diagrama de clases de la aplicación web Ilustración 27: Diagrama de clases de la aplicación móvil Ilustración 25: Clases del paquete vista widget para un usuario La arquitectura de la aplicación widget contiene el paquete modelo, el paquete controladorWIDGET, y los paquetes que contienen las vistas widget. El diagrama de clases será el siguiente: 4.2.2 Diseño de la base de datos Dado que la información que maneja la aplicación es relativamente simple y no hay relaciones complejas entre los datos, el esquema entidad-relación puede derivarse del diagrama de clases. Una vez hemos diseñado el diagrama de clases, para diseñar la base de datos se ha creado una tabla por cada clase que compone el modelo. Cada tabla cuenta con los mismos atributos que la clase correspondiente y como clave primaria se ha seleccionado el atributo id. Para convertir una relación uno-a-muchos se ha agregado la clave primaria del lado uno a la tabla del lado muchos como clave foránea. Esa llave agregada a la tabla del lado muchos no forma parte de su llave primaria, sino que es una columna común. Por ejemplo, la tabla oferta tendrá un campo idEmpresa que corresponderá con el campo id de la empresa que publica la oferta. El diagrama entidad-relación se presenta en la figura siguiente. Para la mejor comprensión del diagrama no se han añadido los atributos de cada entidad que se encuentran en la ilustración 16. La definición de las tablas y de sus atributos se encuentran en el anexo G. 34 Ilustración 28: Diagrama de clases de la aplicación widget Ilustración 29: Diagrama entidad-relación 5 IMPLEMENTACIÓN Durante esta etapa se han implementado, en lenguaje Java, las clases definidas durante la etapa de diseño utilizando los frameworks Vaadin y ORMLite. En esta sección se van a comentar los aspectos de la implementación más importantes y que como desarrollador han supuesto un mayor desafío o han resultado más llamativos o novedosos. Por tanto, no se pretende que esta sección sea un tutorial de desarrollo, sino una forma de exponer los conocimientos o experiencias más importantes que se han adquirido durante el desarrollo del proyecto. El código generado en Vaadin y ORMLite resulta difícil de entender si no se ha utilizado nunca, por eso en el anexo G hay varios ejemplo de programación con esta tecnología 5.1 Acceso de un usuario. En el primer caso vamos a seguir el ejemplo que nos acompaña desde el principio y vamos a seguir el código ejecutado al identificarse un usuario en la aplicación web. Partimos de la pantalla principal en la que hay, entre otras cosas, un formulario para identificarse. El usuario rellena el formulario con sus credenciales y hace clic en el botón “Entrar”. Ésto genera un evento en la vista que se captura en el controlador, el cual llama a la función entrada de la clase lógica. Si los credenciales del usuario son correctos se accede a la aplicación principal para usuarios. //Controlador del botón "Entrar" view.getEntrar().addListener(new Button.clicListener() { /** * */ private static final long serialVersionUID = 1L; /* Handle the clic. */ public void buttonclic(clicEvent event) { //Se llama a la funcion entrada de la clase logica. int valido = logica.entrada(view,idioma); if (valido == 1){//Usuario //Se borran todos los elementos de la ventana y se carga la vista //devuelta por la funcion aplicacionUsuario. vusuario.removeAllComponents(); vusuario.addComponent(aplicacionUsuario(view .getNombre().getValue().toString())); mainwindow.open(new ExternalResource(vusuario .getURL().toString())); La función entrada de la clase lógica busca en la base de datos a que tipo de usuario pertenecen los credenciales introducidos. Devuelve el tipo de usuario si coincide con alguno y un 0 si no coincide con ninguno. /**La función entrada de la clase lógica busca en la base de datos a * que tipo de usuario pertenecen los credenciales introducidos. * @param view: vista con los credenciales del usuario * @param idioma: fichero que contiene los textos de la apicacion * @return 1 si es usuario; 2: si es empresa; 3 si es institución; 4 si es administrador */ public static int entrada(EntradaView view,NProperties idioma) { //Se coge el dirección de correo electrónico del formulario de la vista String nomusuario = (String) view.getNombre().getValue() .toString(); usuario usuario = null; empresa empresa = null; institución institución = null; administrador administrador = null; //Se busca en la base de datos a que tipo de usuario pertenecen el dirección de correo electrónico try { //llama a la función buscarUsuario de la clase DAO usuario = DAO.buscarUsuario(nomusuario); //llama a la función buscarEmpresa de la clase DAO empresa = DAO.buscarEmpresa(nomusuario); //llama a la función buscarinstitución de la clase DAO institución = DAO.buscarinstitución(nomusuario); //llama a la función buscarADminsitrador de la clase DAO 35 administrador = DAO.buscarAdministrador(nomusuario); } catch (SQLException e) { // Si ocurre algun error en el uso de la base de datos se muestra //un mensaje por pantalla y se evia un dirección de correo electrónico al adminsitrador con el fallo. e.printStackTrace(); view.getEntrar().getWindow() .showNotification(idioma.getProperty("problema")); enviarError(idioma.getProperty("errorEntrar"), e); return 0; } //Si borran todos los mensaje de error anteriores. view.getError().removeAllComponents(); if (usuario != null) { //Si el dirección de correo electrónico pertenece a un usuario try { //Se coge la contraseña del formulario. //Si esta en blanco se muestra un mensaje de error if ("".equals((String) view.getClave().getValue() .toString())) { view.añadirError(idioma.getProperty("claveIncorrecta")); } else { //Si la contraseña introducida coincide con el valor de la contraseña //que hay en la base de datos para ese usuario if (usuario.getclave() .equals((String) view.getClave().getValue() .toString())) { //Se actualiza la ultima conexion usuario.setUltimaconexion(usuario .getUltimaconexion1()); usuario.setUltimaconexion1(new Date()); DAO.modificarUsuario(usuario); //Se devuelve un 1. return 1; } else { //Si las contraseñas no coinciden se añade un error al formulario view.añadirError(idioma .getProperty("claveIncorrecta")); } } // } } catch (SQLException e) {// Si ocurre algun error en el uso de la base de datos se muestra //un mensaje por pantalla y se evia un dirección de correo electrónico al adminsitrador con el fallo. e.printStackTrace(); view.getEntrar() .getWindow() .showNotification( idioma.getProperty("problema")); enviarError(idioma.getProperty("errorEntrar"), e); return 0; } Para buscar en la base de datos, La función entrada hace uso de las funciones buscarUsuario(nombre), buscarEmpresa(nombre), buscarinstitución(nombre) y buscarAdministrador(nombre) de la clase DAO. Estas funciones buscan en la base de datos algún dato cuyo id coincida con la variable nombre. /** * busca en la tabla usuario de la base de datos el usuario cuyo id coincide con * id. * @param id: id del usuario buscado * @return devuelve un objeto usuario con la información. Si no existe devuelve null * @throws SQLException Si hay un fallo en la base de datos lanza una excepción. */ public static usuario buscarUsuario(String id) throws SQLException { //Se inicia un objeto usuario. inicialmente con valor null usuario usuario = null; //Se pide una conexion a la base de datos ConnectionSource connectionSource = conectarBd(); //se crea una instancia de la clase dao para buscar en la base de datos Dao<usuario, String> dao = DaoManager.createDao(connectionSource, usuario.class); //Se busca en la base de datos el usuario usuario = dao.queryForId(id); //Se devuelve la conexion 36 devolverBd(connectionSource); //se devuelve el usuario return usuario; } /** * busca en la tabla empresa de la base de datos la emrpesa cuyo id coincide con * id. * @param id: id de la empresa buscada * @return devuelve un objeto empresa con la información. Si no existe devuelve null * @throws SQLException Si hay un fallo en la base de datos lanza una excepción. */ public static empresa buscarEmpresa(String id) throws SQLException { //Se inicia un objeto empresa. inicialmente con valor null empresa empresa = null; //Se pide una conexion a la base de datos ConnectionSource connectionSource = conectarBd(); //se crea una instancia de la clase dao para buscar en la base de datos Dao<empresa, String> dao = DaoManager.createDao(connectionSource, empresa.class); //Se busca en la base de datos la empresa empresa = dao.queryForId(id); //Se devuelve la conexion devolverBd(connectionSource); //se devuelve la empresa return empresa; } /** * busca en la tabla isntitucion de la base de datos la isntitucion cuyo id coincide * con id. * @param id: id de la isntitucion buscada * @return devuelve un objeto isntitucion con la información. Si no existe devuelve null * @throws SQLException Si hay un fallo en la base de datos lanza una excepción. */ public static institución buscarinstitución(String id) throws SQLException { //Se inicia un objeto isntitucion. inicialmente con valor null institución institución = null; //Se pide una conexion a la base de datos ConnectionSource connectionSource = conectarBd(); //se crea una instancia de la clase dao para buscar en la base de datos Dao<institución, String> dao = DaoManager.createDao( connectionSource, institución.class); //Se busca en la base de datos la isntitucion institución = dao.queryForId(id); //Se devuelve la conexion devolverBd(connectionSource); //se devuelve la isntitucion return institución; } /** * busca en la tabla administrador de la base de datos el adminsitrador cuyo id coincide * con id. * @param id: id del adminsitrador buscado * @return devuelve un objeto adminsitrador con la información. Si no existe devuelve null * @throws SQLException Si hay un fallo en la base de datos lanza una excepción. */ public static administrador buscarAdministrador(String id) throws SQLException { //Se inicia un objeto adminsitrador. inicialmente con valor null administrador administrador = null; //Se pide una conexion a la base de datos ConnectionSource connectionSource = conectarBd(); //se crea una instancia de la clase dao para buscar en la base de datos Dao<administrador, String> dao = DaoManager.createDao( connectionSource, administrador.class); //Se busca en la base de datos el adminsitrador administrador = dao.queryForId(id); //Se devuelve la conexion devolverBd(connectionSource); //se devuelve el adminsitrador return administrador; } Una vez que la función entrada ha devuelto el tipo de Usuario se llama a la función aplicacionUsuario del controlador. Esta función llama a la vista AplicacionEmpresaView y se queda 37 esperando un evento. /**funcion que devuelve una vista con las compras de un usuario y gstiona sus eventos * @param id2:dirección de correo electrónico del usuario registrado * @return una vista */ public VerticalLayout aplicacionUsuario(String id2) { //Se configuran las variables de sesion this.id = id2; flagTipoUsuario = 2; //Se pone el flagTpoUsuario a 2, usuario //Se llama a la vista final AplicacionEmpresaView view = new AplicacionEmpresaView( ofertaDia("Registrado"), idioma); //Se añade el logo titulo(view.getTitulo()); /** * Controlador de ventos de la tab principal. Al elegir una pestaña * se crea un evento que dispara esta función. Esta función * intercambia la función que correspondia a la pestaña anterior por * la funcion que corresponde a la pestaña elegida. */ view.getT().addListener(new SelectedTabChangeListener() { /** * Controlador de eventos de la selección de idioma. Al seleccionar * un idioma se crear un evento que dispara esta función que * intercambia el fichero de idioma anterior por el del idioma * elegido. */ view.getSelectIdioma().addListener(new Property.ValueChangeListener() { //Controlador del boton "Salir" view.getSalir().addListener(new Button.clicListener() { //se devuelve la vista return view.getMain(); } La clase AplicacionEmpresaView crea una vista perteneciente a la aplicación principal para usuarios, con una caja de pestañas con varias vistas, un selector de idiomas y un botón salir de la aplicación. Button salir; //boton "salir" VerticalLayout main;//vista VerticalLayout titulo;//espacio reservado para el logo de la aplicacion Select selectIdioma;//caja de seleccion de idioma TabSheet t;//caja de pestañas /** * Función que crea el interfaz de la pantalla principal para usuarios * @param ofertasDiaView: vista con las ofertas del dia * @param idioma */ public AplicacionEmpresaView(VerticalLayout ofertasDiaView, NProperties idioma) { //Se crea y se configura la vista main = new VerticalLayout(); main.setMargin(true); //Espacio reservado dentro de la vista para el logo, el boton salir //y la caja de seleccion de idioma HorizontalLayout h = new HorizontalLayout(); h.setWidth("100%");h.setMargin(true); main.addComponent(h); //Se inicia y se añade el sspacio reservado para el logo de la aplicacion titulo = new VerticalLayout(); titulo.setMargin(true); h.addComponent(titulo); //Se inicia y se añade el sspacio reservado para la caja de seleccion de idioma VerticalLayout EspacioIdioma = new VerticalLayout(); h.addComponent(EspacioIdioma); //Se crea y se añade el boton "salir" salir = new Button(idioma.getProperty("salir")); salir.setStyleName("ofertastheme"); h.addComponent(salir); //Se iniciliza la caja de selección de idioma. //Se añaden las opciónes a elegir, se configura y se añade al espacio //reservado para su visualización selectIdioma = new Select(idioma.getProperty("seleccionIdioma")); selectIdioma.addItem(idioma.getProperty("castellano")); selectIdioma.addItem(idioma.getProperty("gallego")); // select1.addItem(idioma.getProperty("administrador")); selectIdioma.setImmediate(true); selectIdioma.setNewItemsAllowed(true); EspacioIdioma.addComponent(selectIdioma); /** Se inicializa la caja de pestañas y se añaden los contenidos. 38 * Inicialmente solo "ofertasDia" tiene contenido. Los demas contenidos se añaden en el momento en el que pulsas sobre la pestaña. Esto se hace desde el controlador * que se encuentra en OfertasApplication en la funcion OfertasApplication. * Se añade a la ventana fisica principal.*/ t = new TabSheet(); t.setHeight("100%"); t.setWidth("100%"); t.addTab(ofertasDiaView, idioma.getProperty("ofertasDia")); t.addTab(new VerticalLayout(), idioma.getProperty("alrededor")); t.addTab(new VerticalLayout(), idioma.getProperty("guíaCiudad")); t.addTab(new VerticalLayout(), idioma.getProperty("buscar")); t.addTab(new VerticalLayout(), idioma.getProperty("comoFunciona")); t.addTab(new VerticalLayout(), idioma.getProperty("favoritos")); t.addTab(new VerticalLayout(), idioma.getProperty("miCuenta")); t.addListener(this); main.addComponent(t); } 5.2 Cambio de idioma Uno de los requisitos del sistema es que debe poder utilizarse en diferentes idiomas. Para implementar este requisito se ha hecho uso de los ficheros properties de java que son ficheros de texto donde almacena por cada línea, un par clave valor que representan el nombre de la variable y su valor. Una cadena se guarda en el fichero properties escribiéndola de la siguiente manera: guíaCiudad = LA guía DE MI CIUDAD Donde guiaCiudad es la clave y LA GUÍA DE MI CIUDAD es el valor. Para conseguir una cadena del fichero utilizamos el siguiente comando. idioma.getProperty("guíaCiudad") Se ha creado un fichero properties por cada idioma en el que se podrá mostrar la aplicación. Todos los ficheros tienen las mismas claves y se diferencian en los valores, ya que cada uno contiene los valores en su idioma. Guardando las cadenas en un fichero properties tenemos varias ventajas. Una es que, como ya hemos visto, se puede hacer una aplicación multi-idioma fácilmente. Otra es que si una cadena aparece varias veces en la aplicación, y la queremos modificar, basta con cambiarla en el fichero properties. Cuando el usuario cambia el valor del campo de selección de idioma de la pantalla principal se crea un evento que se captura en la función aplicacionUsuario del controlador. Una vez capturado, se llama a la función cambiarIdioma de la clase lógica para cargar el fichero properties correspondiente al idioma seleccionado y se hace un reset de la pantalla principal. /** * Controlador de eventos de la selección de idioma. Al seleccionar * un idioma se crear un evento que dispara esta función que * intercambia el fichero de idioma anterior por el del idioma * elegido. */ view.getSelectIdioma().addListener(new Property.ValueChangeListener() { /** * */ private static final long serialVersionUID = 1L; public void valueChange( com.vaadin.data.Property.ValueChangeEvent event) { if (event.getProperty().getValue() != null) { //Se llama a la clase cambiar idioma de la clase logica idioma = logica.cambiarIdioma(view.getSelectIdioma() .getValue().toString(),idioma); /** Se hace un reset de la pantalla. Primero se borran todos los elementos. */ view.getSelectIdioma().getWindow().removeAllComponents(); 39 /** * Despues se vuelve a cargar ya con el nuevo idioma. */ vusuario.addComponent(aplicacionUsuario(id)); } } }); La función cambiarIdioma de la clase lógica llama a la clase NProperties con el idioma seleccionado. Esta función devuelve una instancia de un fichero properties con los textos de la aplicación en el idioma seleccionado. /**Funcion para cambiar el idioma de la aplicacion * @param seleccion: idioma seleccionado * @param idioma: instancia de fichero properties con los textos del idioma anterior. * @return: instancia de fichero properties con los textos del nuevo idioma. */ public static NProperties cambiarIdioma(String seleccion, NProperties idioma) { /** * Si la opción elegida es "castellano" se carga el fichero de idioma castellano */ if (seleccion .equals(idioma.getProperty("castellano"))) { /** * Nproperties es una clase que carga el fichero de idioma que le pides. * En este caso el español. */ idioma = new NProperties("ES"); } /** * Si la opción elegida es "gallego" se carga el fichero de idioma gallego */ if (seleccion .equals(idioma.getProperty("gallego"))) { idioma = new NProperties("GL"); } return idioma; } La clase NProperties es una clase que devuelve una instancia de fichero properties con los textos en idioma seleccionado. /** * Constructor de la clase NProperties * * @param idioma: idioma seleccionado */ public NProperties(String idioma) { if (idioma.equals("ES")) { // devuelve una instancia de dichero // properties con los textos en español getProperties("../Properties/español.properties"); } else if (idioma.equals("GL")) { // devuelve una instancia de dichero // properties con los textos en gallego getProperties("../Properties/gallego.properties"); } else { // por defecto devuelve una instancia de dichero // properties con los textos en gallego getProperties("../Properties/español.properties"); } } /* se leen las propiedades */ public void getProperties(String idioma) { try { this.load(getClass().getResourceAsStream(idioma)); } catch (IOException ex) { } } 5.3 Geolocalización Cuando el usuario se conecta desde un móvil a la aplicación móvil, ésta recoge sus coordenadas y calcula cual es la provincia en la que esta usando una funcionalidad de google maps. Cuando se inicia una aplicación desarrollada con Vaadin en un navegador se obtienen los 40 detalles del navegador (que navegador es, tamaño, etc) mediante la función onBrowserDetailsReady. Uno de estos detalles son las coordenadas. /** * Funcion que contiene los detalles del navegador en el que se ejecuta la aplicacion * en la que esta. */ @Override public void onBrowserDetailsReady() { //obtiene localizacion mainwindow.detectCurrentPosition(new PositionCallback() { public void onSuccess(Position position) { //Coordenada X double latitude = position.getLatitude(); //Coordenada / double longitude = position.getLongitude(); //Precision double accuracy = position.getAccuracy(); A partir de ellos podemos saber cual es la provincia desde la que se esta usando la aplicación. Para eso usamos la funcionalidad Geocode de Google Maps pasándole como parámetros las coordenadas y nos devolverá contenido con información de nuestra posición, calle, ciudad, provincia, etc. //Preparamos una petición a la funcionalidad Geocode de Google Maps URI uri = new URI("http://maps.google.com/maps/api/geocode/json? latlng="+latitude+","+longitude+"&sensor=true"); httpGet.setURI(uri); //ejecutamos la peticion HttpResponse httpResponse = httpClient.execute(httpGet); //cogemos el contenido de la respuesta y lo metemos en un buffer InputStream contenido = httpResponse.getEntity().getContent(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(contenido)); //Pasamos el contenido del buffer a la cedena texto String ligneLue; ligneLue = bufferedReader.readLine(); String texto=""; while(ligneLue !=null) { texto=texto+ligneLue; texto=texto+"\n"; ligneLue = bufferedReader.readLine(); } Pasamos la información del contenido a tipo String. //Pasamos el contenido del buffer a la cedena texto String ligneLue; ligneLue = bufferedReader.readLine(); String texto=""; while(ligneLue !=null) { texto=texto+ligneLue; texto=texto+"\n"; ligneLue = bufferedReader.readLine(); } Dentro de la cadena texto hay mucha información sobre nuestra posición. Lo que nos interesa en este caso es la provincia en la que se encuentra el usuario. Esta información se encuentra tras la subcadena long_name de la siguiente manera: "long_name" : "Corunna" Por lo tanto, para conseguir la localización, hay que buscar el valor de la clave long_name en la cadena texto y guardarlo en la variable global Provincia. //separamos el texto por espacios en blanco String[] arrayBuscar = texto.split(" "); //Se busca la clave "long_name" que es la que contiene la Provincia for (int i = 0; i < arrayBuscar.length; i++) { if(((arrayBuscar[i]).indexOf("long_name"))!=-1){ //cuando se ha encontrado se guarda su valor en la variable global Provincia Provincia = arrayBuscar[i+2]; //adaptamos el valor devuelto al castellano. if ((Provincia.indexOf("Corunna"))!=-1){Provincia="La Coruña";} } 41