Desarrollo de una aplicación Web 2.0 para la captura y análisis de la valoración del usuario
Full text
Desarrollo de una aplicación Web 2.0 para la captura y análisis de la valoración del usuario Proyecto Final De Carrera Aurelio Segura Maroto 13/09/2010 Directores: Pedro José Valderas Aranda Estefanía Serral Asensio
A Baldomero, Concha y Marina
Índice 1. Introducción 4 1.1. Objetivos ............................. 4 1.2. Motivación............................. 4 1.3. ¾Qué es una ontología? . . . . . . . . . . . . . . . . . . . . . . 5 1.4. Estructura de la memoria . . . . . . . . . . . . . . . . . . . . 8 2. Herramientas y Tecnologías 9 2.1. Herramientas ........................... 10 2.1.1. Eclipse........................... 10 2.1.2. Protégé .......................... 11 2.1.3. Tomcat .......................... 13 2.1.4. Jena............................ 13 2.1.5. Jastor ........................... 14 2.2. Tecnologías ............................ 14 2.2.1. HTML........................... 15 2.2.2. CSS ............................ 15 2.2.3. JEE ............................ 15 2.2.4. JSF ............................ 16 2.2.5. JFreeChart ........................ 17 2.2.6. SPARQL.......................... 18 1
3. Implementación 19 3.1. Modelo............................... 19 3.2. APIOWL............................. 20 3.3. Mapeo de OWL a Java . . . . . . . . . . . . . . . . . . . . . . 21 3.4. ClasesDAO............................ 24 3.5. Login................................ 28 3.6. EstadoActual .......................... 28 3.7. Histórico.............................. 34 3.8. Estadísticas ............................ 41 3.9. Otros aspectos considerados . . . . . . . . . . . . . . . . . . . 46 4. Interfaz de Usuario 48 5. Instalación 51 6. Conclusiones 52 2
Índice de guras 1. Patrón DAO Diagrama de clases . . . . . . . . . . . . . . . . . 25 2. Patrón DAO Diagrama de secuencia . . . . . . . . . . . . . . . 27 3. GrácodeEventos ........................ 41 4. Gráco de eventos durante la última semana . . . . . . . . . . 42 5. PatternsExecution........................ 44 6. Environment Properties . . . . . . . . . . . . . . . . . . . . . 45 7. Devices .............................. 46 8. System Information . . . . . . . . . . . . . . . . . . . . . . . . 49 9. Statistics.............................. 50 3
1. Introducción 1.1. Objetivos El presente documento describe el trabajo realizado en el proyecto: Desarrollo de una aplicación Web 2.0 para la captura y análisis de la valoración del usuario. El objetivo principal del proyecto es mostrar la información de un entorno inteligente. Para ello se ha pensado que la forma más cómoda para el usuario era mostrarlo mediante una aplicación web. En este Proyecto Fin de Carrera se quiere un portal web dinámico para mostrar información sobre un entorno inteligente intentando que cubra todas las necesidades del usuario. El portal que se desea desarrollar servirá para mostrar toda la información relevante para el usuario. Al ser una aplicación web esta información se podrá consultar desde cualquier parte, esto permitirá al usuario saber en cada momento, aunque no se encuentre físicamente en el entorno inteligente, cual es el estado del mismo. También se quiere crear un completo histórico de los eventos que han ocurrido. De esta manera el usuario podrá ver, de forma cómoda los eventos ocurridos en los últimos días aunque también tendrá la oportunidad de ver los eventos que se ejecutaron en cualquier día en concreto. Hay que destacar que este Proyecto Final de Carrera es un subproyecto de uno más grande sobre sistemas pervasivos que se está llevando a cabo en el Centro de Investigación de Métodos de Producción de Software (ProS) de la Universidad Politécnica de Valencia. 1.2. Motivación La principal motivación de este Proyecto Final de Carrera ha sido el interés de la tecnología requerida para realizar adecuadamente el proyecto. Las 4
tecnologías web han ido creciendo exponencialmente a medida que se ha ido incrementando el uso de internet en la población. Además, con el aumento de la tecnología en los hogares, la domótica es una rama que ha ido aumentando en los últimos años. Este proyecto me ha dado la posibilidad de ampliar mis conocimientos sobre este tema. Es importante destacar que en este Proyecto Final de Carrera se han utilizado conceptos de alto nivel de abstracción en una ontología. Una ontología busca catalogar la información de los recursos. Con las ontologías, los usuarios organizarán la información de manera que los agentes de software podrán interpretar el signicado y, por tanto, podrán buscar e integrar datos mucho mejor que ahora. Gracias al conocimiento almacenado en las ontologías, las aplicaciones podrán extraer automáticamente datos, procesarlos y sacar conclusiones de ellos, así como tomar decisiones y negociar con otros agentes o personas. Se ha generado un API para usar la ontología en un nivel alto de abstracción, de esta manera el código es menos sensible a cambios en la ontología, mejora su reutilización y mantenimiento. Por último, quiero destacar que este proyecto ha representado una gran oportunidad para aprender nuevas tecnologías. 1.3. ¾Qué es una ontología? Las ontologías proceden del campo de la Inteligencia Articial; son vocabularios comunes para las personas y aplicaciones que trabajan en un dominio. Según el Grupo de Trabajo en Ontologías del consorcio W3C, una ontología dene los términos que se usan para describir y representar un cierto dominio. Uso la palabra dominio para denotar un área especíca de interés (el río Duero, por ejemplo) o un área de conocimiento (física, aeronáutica, medicina, contabilidad, fabricación de productos, etc.). Toda ontología representa cierta visión del mundo con respecto a un dominio. Por ejemplo, una 5
ontología que dena ser humano como espécimen vivo o muerto correspondiente a la especie Homo sapiens; primate bípedo que pertenece a la familia de los homínidos, como los chimpancés, gorilas y orangutanes expresa una visión del mundo totalmente distinta a la de una ontología que lo dena como sujeto consciente y libre, centro y vértice de todo lo que existe; todos tienen la misma dignidad, pues han sido creados a imagen y semejanza de Dios. Cualquier persona tiene en su cabeza ontologías mediante las que representa y entiende el mundo que lo rodea. Estas ontologías no son explícitas, en el sentido de que no se detallan en un documento ni se organizan de forma jerárquica o matemática. Todos usamos ontologías en las que Automóvil representa un medio de transporte y tiene cuatro ruedas. ¾Formalizamos este tipo de ontologías? No, sería innecesario: los automóviles son tan habituales que todos compartimos la información de lo que son. Lo mismo sucede cuando pensamos en el dominio familiar: sabemos que una familia se compone de varios miembros, que un hijo no puede tener más de un padre y una madre biológicos, que los padres tienen o han tenido padres... No necesitamos explicitar este conocimiento, pues forma parte de lo que todo el mundo sabe. Sin embargo, cuando se tratan términos poco comunes o cuando se quiere que estos términos sean procesados por máquinas, se precisa explicitar las ontologías; esto es, desarrollarlas en un documento o darles una forma que sea inteligible para las máquinas. Las máquinas carecen de las ontologías con las que nosotros contamos para entender el mundo y comunicarse entre ellas; por eso necesitan ontologías explícitas. En cuanto dos sistemas de información (sistemas ERP, bases de datos, bases de conocimiento) intentan comunicarse, aparecen problemas semánticos que dicultan o imposibilitan la comunicación entre ellos . Los problemas semánticos son de dos tipos: de dominio y de nombre. Los con- ictos de dominio aparecen cuando conceptos similares en cuanto a signi- cado, pero no idénticos, se representan en distintos dominios. Por ejemplo, el concepto representado por Trabajador en una base de datos (BD) puede 6
corresponder a un trabajador cualicado, mientras que otra BD puede usar Trabajador para cualquier trabajador, sea o no cualicado. Ambos conceptos están muy vinculados, pero no son equivalentes ni deberían mezclarse. Usando ontologías, podría especicarse que el primer concepto corresponde a una especialización del segundo; y un sistema de razonamiento automático basado en ontologías impediría, por ejemplo, que se contratara para tareas cualicadas a trabajadores no cualicados. En la ingeniería del software, las ontologías ayudan a la especicación de los sistemas de software. Como la falta de un entendimiento común conduce a dicultades en identicar los requisitos y especicaciones del sistema que se busca desarrollar, las ontologías facilitan el acuerdo entre desarrolladores y usuarios. Exiten diferentes lenguajes para implementar una ontología, en este Proyecto Final de Carrera se ha usado OWL (Ontology Web Language). OWL se compone de las siguientes características: Clase: Una clase dene un grupo de individuos que se agrupan por que comparten una serie de propiedades. Por ejemplo, Peter y David son miembros de la clase Persona. Las clases pueden ser organizadas en una jerarquia de especialización mediante el uso de subClassOf. Hay una clase, llamada Thing, que es superclase de todas las clases de OWL. Una clase puede contener propiedades, estas propiedades (o atributos) contienen la información de las instacias (en OWL al concepto de instancia se le denomina Individual). Propiedad: Las propiedades contienen la información de las instancias de una clase. El dominio de propiedad indica qué clases tendrán esa propiedad. El Rango de una propiedad indica de qué tipo van a ser los datos que va a contener esa propiedad. Hay dos tipos de rangos, el de objects en el cual el rango será una clase de la ontología o el 7
Un API RDF Leer y escribir RDF en RDF/XML, N3 y N-Triples Un API OWL Almacenamiento en memoria y persistente. Motor de consultas SPARQL 2.1.5. Jastor Jastor es un generador de código abierto en Java que emite JavaBeans desde una ontología Web (OWL) permitiendo acceso seguro y cómodo a todo el RDF almacenado en un modelo Jena. Jastor genera las interfaces Java, las implementaciones, las fábricas y los oyentes según las propiedades y las jerarquías de clase en la Ontología Web. 2.2. Tecnologías Para la implementación de la aplicación web se han utilizado diferentes tecnologías y lenguajes de programación para implementar la parte gráca y la lógica del portal web. A continuación se van a comentar las diferentes tecnologías usadas en la implementación de este Proyecto Final de Carrera. Como servidor de aplicaciones se ha utilizado para hacer las pruebas, como se ha comentado antes, Apache Tomcat 6.0 aunque no debería haber ningún problema en usar otro servidor de aplicaciones (como podría ser jboss por ejemplo). Para el diseño de la interface de nivel de presentación se ha utilizado HTML combinándolo con hojas de estilo CSS. La tecnología web usada en la aplicación ha sido JEE y JSF. 14
2.2.1. HTML HTML, siglas de HyperText Markuo Language (Lenguaje de Marcas de Hipertexto), es el lenguaje de marcado predominante para la construcción de páginas web. Se utiliza para describir la estructura y el contenido en forma de texto, así como para complementar el texto con objetos tales como imágenes. HTML se forma de etiquetas, rodeadas por corchetes angulares(<,>). HTML también puede describir, hasta un cierto punto, la apariencia de un documento, y puede incluir un script ( por ejemplo Javascript), el cual puede afectar el comportamiento de navegadores web y otros procesadores de HTML. 2.2.2. CSS Las hojas de estilo en cascada (Cascading Style Sheets, CSS) son un lenguaje formal usado para denir la presentación de un documento estructurado escrito en HTML o XML. El W3C (World Wide Web Consortium) es el encargado de formular la especicación de las hojas de estilo que servirán de estándar para los agentes de usuario o navegadores. La idea que se encuentra detrás del desarrollo de CSS es separar la estructura de un documento de su presentación. 2.2.3. JEE Java EE (Java Enterprise Edition) es una plataforma de programación para desarrollar software en lenguaje Java que pueda ser ejecutado en un servidor de aplicaciones. JEE diere de Java Standard Edition (Java SE) en que añade las librerías que proporcionan funcionalidad para desplegar tolerancia a fallos, distribuida, multi nivel, basado en modular los componentes que se ejecutan en un servidor de aplicaciones. 15
La plataforma era conocida como Java 2 Enterprise Edition (J2EE) hasta que el nombre fue cambiado a Java EE en la versión 5. Java EE está denida por sus especicaciones. Al igual que con otras especi- caciones de Java Community Process, los proveedores deben cumplir con ciertos requisitos de conformidad para declarar sus productos conformes a Java EE. Java EE incluye varias API, como JDBC, RMI, email, JMS, servicios web, XML ... y dene cómo coordinarlas. Java EE también congura algunas especicaciones únicas para componentes. Éstas incluyen Enterprise JavaBeans, conectores, servlets, portlets, JavaServerPages y varias tecnologías de servicios web. Esto permite a los desarrolladores crear aplicaciones empresariales que son portables y escalables, y que se integran con las tecnologías anteriores. Un servidor de aplicación Java EE puede manejar transacciones, seguridad, escalabilidad, concurrencia y gestión de los componentes desplegados, con el n de permitir a los desarrolladores concentrarse más en la lógica de negocio en lugar de la infraestructura y las tareas de integración. 2.2.4. JSF Java Server Faces (JSF) es un framework de aplicaciones web basado en Java destinado a simplicar el desarrollo y la integración de las interfaces de usuario. JSF está basado en un framework MVC de desarrollo web basado en el componente impulsando el diseño del modelo de la interfaz de usuario. Las solicitudes son procesadas por el FacesServlet, que carga la vista apropiada de la plantilla, construye el árbol de componentes, los procesos de eventos y hace una respuesta (HTML) al cliente. El estado de los componentes de la IU (Interfaz de usuario) se guarda al nal de cada solicitud y es restaurado en la siguiente creación de la vista. JSF 2 utiliza facelets para su tecnología de pantalla por defecto. 16
Existen diversas implementaciones de JSF, para este Proyecto Final de Carrera se ha utilizado Apache MyFaces 2. Además se ha utilizado también Apache TomaHawk que es un conjunto de componentes JSF creado por el equipo de desarrollo de MyFaces. 2.2.5. JFreeChart JFreeChart es una librería Java de código abierto que facilita a los desarrolladores mostrar grácos de calidad profesional en sus aplicaciones. JFreeChart incluye: Una consistente y bien documentada API, que soporta una amplia gama de tipos de grácas. Diseño exible que es fácil de ampliar, y que se dirige tanto del lado del servidor como de las aplicaciones del lado del cliente. Apoyo a muchos tipos de salida, incluyendo componentes Swing, archivos de imagen y grácos vectoriales. Se soportan los siguientes tipos de grácas: Los grácos XY (línea,dispersión...) Grácos circulares Gantt Barras (horizontales y verticales, apiladas o independientes) Un solo valor (termómetro, brújula, indicador de velocidad) 17
2.2.6. SPARQL SPARQL es un lenguaje de consulta RDF, su nombre es un acrónimo recursivo que signica S PARQL P rotocol a nd R DF Q uery L anguage. Fue estandarizado por RDF Data Access Working Group (DAWG) del World Wide Web Consortium y se considera clave de la tecnología web semántica. SPARQL permite consultas de patrones triples, conjunciones, disyunciones y patrones opcionales. 18
3. Implementación Para este Proyecto Final de Carrera se ha utilizado el dominio de una casa domótica. 3.1. Modelo Se ha proporcionado por parte de los directores del proyecto la ontología de contexto y el metamodelo de tareas. El modelo de contexto contiene toda la información sobre el estado de la vivienda domótica además también posee la información sobre los eventos que se han ido ejecutando en el sistema. Las principales clases de este modelo son: ContextModel: Contiene toda la información del sistema, desde esta clase es desde donde se puede navegar a cualquier clase del modelo. User: Representa información sobre un usuario, su información personal, la información para poder acceder a la aplicación, la localización dentro de la vivienda, preferencias que tiene (por ejemplo a qué hora se levanta), las políticas que tiene ... Location: Representa un sitio de la casa (cocina, comedor, baño...) contiene información de las propiedades del entorno que tiene y de los servicios además de tener información de a qué otras habitaciones se pueden acceder desde ella. Service: Representa un servicio de la vivienda, contiene la información del estado del servicio, de los métodos que tiene dicho servicio además de dónde se encuentra ese servicio y a la categoría que representa dicho servicio. 19
Event: Representa un Evento que ha ocurrido en el sistema, el modelo tiene 4 tipos de eventos: BehaviourPatternExecution, ContextChange, DeviceEvent, UserAction. Para todos ellos se conoce la fecha y la hora en la que ocurrió el evento. Después para cada evento en particular se conocen otros detalles como por ejemplo para el BehaviourPatternExecution el patrón que se ejecutó, para el UserAction el usuario y el método que se ejecutó ... PatternExecution: Representa un patrón de ejecución, es la clase que une a los dos meta modelos dado que en el modelo de características lo que se encuentra es el detalle del Patrón. Un patrón de comportamiento es un conjunto de tareas que se suelen llevar a cabo en contextos similares. Por ejemplo, algunos patrones de comportamiento pueden ser determinados por nuestro ciclo de vida, como leer el correo electrónico y abrir ciertas páginas web tan pronto como tengamos conexión a Internet, mientras que otras son reacciones a cosas que suceden a nuestro alrededor. Para más información sobre un PatternExecution se puede consultar [2] El modelo de tareas como se ha dicho contiene la información sobre cada patrón de comportamiento denido en el sistema. 3.2. API OWL API es una clase Java que tiene todo lo necesario para leer un chero OWL. Para ello usa el framework Jena para poder leer un chero OWL. El API OWL contiene una serie de métodos que permiten hacer consultas SPARQL directamente sobre el chero. Dado que las consultas que se tienen que hacer en este proyecto son siempre las mismas se crearon métodos auxiliares que solamente tuvieran estas consultas. 20
Con el propósito de hacer lo más independiente posible la aplicación web del método de almacenamiento de los datos se ha utilizado el patrón de diseño DAO. La aplicación web lee los datos de las clases DAO creados y éstos cuando se crean son los que llaman al API para recibir los datos. En el caso de que en un futuro los datos se pasen a guardar en otro formato diferente solamente habría que cambiar las clases DAO creadas para que leyeran los datos del nuevo método. Dado que el chero donde se encuentra la ontología podía cambiar de localización se decidió cargar la información de éste de forma dinámica. Para ello se ha utilizado un chero properties para almacenar la información de la URI donde se encuentra la ontología. La librería JENA trabaja preferiblemente con uris y no con rutas físicas para cargar las ontologías (aunque tiene métodos que permiten leer de rutas físicas). 3.3. Mapeo de OWL a Java Aunque al principio del proyecto no se consideró necesario, conforme avanzaba el mismo se vio que sería interesante poder almacenar la información en objetos Java equivalentes a los de la ontología. De esta manera se podía aumentar el nivel de abstacción usado beneciando su mantenimiento y reutilización. Un dato importante en este mapeo era poder hacerlo de manera automática por si se realizaba algún cambio en la ontología o para poder reutilizarlo en otras ontologías. La primera intención era, utilizando el API OWL y el código generado del ecore del modelo de contexto hacer a mano el mapeo. La idea fue descartada dado que hacerlo de forma artesanal haría que cualquier pequeño cambio en la ontología habría que volver ha realizar a mano el mapeo y aunque para un pequeño cambio a lo mejor no fuera mucho esfuerzo en un cambio con clases y relaciones la dicultad y el tiempo podrían ser un problema. 21
Finalmente se decidió intentar encontrar algún proyecto que fuera similar a hibernate pero para OWL. Se probaron diferentes proyectos y al nal se ha optado por usar una especie de plugin de Jena llamado Jastor que genera automáticamente las interfaces, las implementaciones, las factorías.... Aparte de éste se probaron otros proyectos: Protégé: La versión de Protégé usada en la realización del proyecto tiene un plugin que genera directamente las interfaces y las implementaciones además de una clase Factoría para poder acceder a las instancias del modelo. El problema fue a la hora de usarlo daba errores en algunas librerías del API y no se podía usar. Las nuevas versiones de Protégé no tienen este plugin y la documentación de la página no ayudó a saber qué tipo de incompatibilidad había. La conclusión a la que llegamos que las versiones Java utilizadas por las librerías y las usadas para este proyecto no serían las mismas 1.5 a 1.6 y algún método podría haber cambiado. JAOB: JAOB otra librería usada, igual que Protégé también generaba automáticamente las instancias. A diferencia de Protégé esta librería no daba error ni incompatibilidades y parecía recuperar bien las instancias. Al nal nos dimos cuenta de que algunos atributos no eran recuperados correctamente y aparecían atributos a null, por eso se decidió descartar esta librería. De todas maneras la librería estaba muy bien documentada, además en su página web había un estudio hecho por parte del autor de diversas librerías que hacían lo mismo que la suya. Este estudio ayudó dado que fue más fácil localizar la herramienta que al nal terminamos utilizando. Kazuki: En el mismo Protégé también había la opción de generar las clases para Kazuki, aunque este plugin daba error. La idea de probar esta librería fue por la documentación que tenía en la página web. El problema fue similar al ocurrido con el de Protégé, en el código fuente 22
tenía un error en una llamada a una función de Java que había cambiado y no se podía usar. Jastor: Esta librería hace uso del API de Jena. Con ésta se pueden generar automáticamente las interfaces, las implementaciones, las factorías y los oyentes, con lo cual si hay algún cambio en el modelo OWL se podría volver a generar todo de forma rápida. El principal problema de Jastor es la poca documentación que había sobre la librería, la mayoría de la documentación hace referencia a cómo crear objetos en Java con las clases generadas y cómo almacenarlos en un modelo OWL, justamente lo contrario de lo que nosotros queríamos. Al nal logramos utilizar la librería para los usos que le queríamos dar (mapear los Individuals en instancias Java). Jastor genera una clase Factory desde donde se pueden acceder a todos los Individuals del modelo, cada clase tiene dos métodos (uno para recuperar una instancia de la clase y otra que recupera la lista de instancias). Con las pruebas realizadas comprobamos que recuperamos satisfactoriamente las instancias sin el problema que teníamos usando JAOB. Al nal el proyecto que utilizamos para hacer el mapeo fue el que generaba correctamente toda la información de la ontología, el principal problema de la mayoría de proyectos vistos (aparte de los citados arriba se vieron otros pero no se probaron ni testearon) es la poca documentación diponible y que la mayoría llevaban varios años abandonados. Una de las cosas que hay que tener en cuenta a la hora de trabajar con las clases generadas por la herramienta es que en OWL los atributos pueden ser todos multievaluados. Por ejemplo, la clase Event tiene un atributo fecha, que por denición del modelo solamente tendrá 1 solo valor, en un modelo OWL se puede poner cardinalidad para especicar que ese atributo solamente podrá tener 1 valor pero la herramientas de mapeo suele tener limitaciones y algunas de estas limitaciones es la comentada anteriormente, no saben 23
<h: outputText value="(#{node . childCount })" styleClass=" childCount" rendered="#{! empty node . children }" /> </h:panelGroup> </f : facet> <f : facet name="Service"> <h:panelGroup> <h: outputText value="#{node . description}" /> </h:panelGroup> </f : facet> </t : tree2> El código anterior muestra un ejemplo del árbol, se pueden comprobar dos tipos claros de facet, el ServiceLocation y el Service. El primero será un TreeNodeBase con el atributo de hoja a false y el segundo con el atributo de hoja a true. Dentro del facet se pueden usar otros elementos JSF (en este caso se han usado outputText pero se podrían haber usado imágenes por ejemplo) de esta manera las posibilidades de personalizar el árbol son enormes. Se han implementado dos BEANs para generar el árbol: El primer BEAN que se creó se usó leyendo los datos de las clases DAO, una vez recuperados los datos de las clases se procedía a ir construyendo el árbol de arriba a abajo, por ejemplo para construir la parte del árbol de servicios organizados por localización se hacía de la siguiente manera. Primero se recuperaban las localizaciones del sistema utilizando LocationDAO, una vez recuperadas para cada localización se recuperaba la lista de servicios que tenía esa localización. El siguiente fragmento de código muestra como se ha hecho. 30
//treeData es representa al árbol general ArrayList<String> locations = new LocationDAO( lb . getApi () ) . getLocations () ; TreeNodeBase ServicesLocations = new TreeNodeBase(" ServiceLocation" , "Services group by Location" , false ) ; for ( int i = 0; i < locations . size () ; i++) { ArrayList<Map<String , String>> services= new ServiceLocationDAO( lb . getApi () , locations . get (i)).getServices(); TreeNodeBase location = new TreeNodeBase(" Location" , locations . get ( i ) , false ) ; if ( services . size () >0) { for ( int j = 0; j < services . size () ; j ++) location . getChildren () . add( new TreeNodeBase("Service" , services . get ( j ) . get ("name")+ " − "+services . get ( j ) . get (" state") , true ) ) ; } ServicesLocations . getChildren () .add( location ) ; } treeData . getChildren () . add( ServicesLocations ) ; Como se ha comentado anteriormente, mientras el proyecto avanzaba nos dimos cuenta de que igual era cómodo tener los individuals de OWL en instancias de Java. Una vez que se logró hacer funcionar la librería Jastor decidimos cambiar el BEAN creado para el Estado Actual y en vez de usar las clases DAO utilizar la librería Jastor para recuperar las instancias. 31
De esta manera se creó un nuevo BEAN exactamente igual que el anterior pero utilizando Jastor en vez de las clases DAO. Ahora en vez de crear la clase DAO y recuperar los datos lo que se hace es llamar al Factory generado por Jastor pasándole el modelo Jena y pidiéndole que devuelva todas las instancias de la clase que necesitamos. List loc =Factory . getAllLocation (model) ; TreeNodeBase ServicesLocations = new TreeNodeBase(" ServiceLocation " , " Services group by Location " , false ) ; for ( int i = 0; i < loc . size () ; i++) { LocationImpl locimp = (LocationImpl) loc .get(i) ; Iterator locname=locimp . getName() ; i f (locname . hasNext () ) { TreeNodeBase location=location=new TreeNodeBase(" Location " , locname . next () . toString () , false ) ; Iterator ser=locimp . getServices () ; while ( ser . hasNext () ) { ServiceImpl serimpl= ( ServiceImpl ) ser . next () ; Iterator sername=serimpl . getName() ; Iterator serstate=serimpl . getState () ; String serstring =""; i f (sername . hasNext () ) 32
serstring+=sername . next () ; i f ( serstate . hasNext () ) serstring+=" − "+ serstate . next () ; i f ( serstring . length () >0) location . getChildren () . add(new TreeNodeBase (" Service " , serstring , true ) ) ; } ServicesLocations . getChildren () . add( location ) ; } } treeData . getChildren () . add( ServicesLocations ) ; Como se puede comprobar en el código anterior, todos los atributos son listas (Iterators), aunque se sepa que el atributo va a tener un único valor (el name y el state es un ejemplo). El desarrollador tiene que tener esto en cuenta a la hora de acceder a dichos atributos. Si comparamos el código necesario para hacer este BEAN y para hacer el anterior BEAN parece que a primera vista hacerlo usando Jastor es mucho más laborioso que haciéndolo usando las clases DAO. La realidad es que después de generar con Jastor el único código que hay que usar es el puesto arriba, si no usamos Jastor lo primero que tendríamos que hacer es realizar las consultas necesarias en SPARQL, segundo crear las clases DAO y tratar los datos de la consulta y devolverlos en un formato cómodo, por último tendríamos que acceder a esos datos como se ha puesto anteriormente. Al nal, dependiendo de lo que queramos mostrar y de la situación se podrá usar un método u otro para recuperar la información. 33
3.7. Histórico Una parte de la información más interesante que tiene el modelo es la relativa a los eventos que se han ido ejecutando a lo largo del tiempo en la vivienda. Por esta razón se ha intentado crear una forma cómoda para consultar dicha información. Por un lado queríamos que la información fuera fácil de acceder, al nal optamos por una representación en forma de árbol donde los eventos estuvieran organizados entre los ejecutados hoy, ejecutados ayer, ejecutados durante la última semana y los ejecutados durante el último mes. Además de esa información también se quería que se pudiera consultar cualquier día para ver qué eventos se habían ejecutado ese día en concreto. En el momento de hacer esta sección nos paramos a pensar con qué método de los dos que teníamos se haría más fácil y cómodo (de las clases DAO o el de Jastor). Como se ha comentado anteriormente se disponía de Jena que permite consultas SPARQL con lo cual es muy fácil y rápido pedirle al API que te devuelva la información de los eventos que han ocurrido en un día en concreto (o en una franja de días), mediante Jastor únicamente tenemos el método para recuperar todas las instancias de una clase, después estas instancias deberán ser tratadas y ordenadas para mostrarse. Dado que el hecho de ir instancia a instancia comprobando que era muy costoso se decidió que para el histórico lo mejor era utilizar el motor SPARQL que al ser un lenguaje de consultas que tenía implementado el order by devolvía la información en el orden exacto en el que se quería mostrar. Se ha comentado también que el modelo de contexto tiene cuatro tipos diferentes de eventos. En el modelo de contexto estas cuatro clases heredan de Event pero en SPARQL no se podían recuperar los eventos dado que no había ningún individual de la clase Event (eran o BehaviourPatternExecution, o ContextChange, o DeviceEvent, o UserAction) por esta razón se pensó que lo mejor era hacer el histórico para cada tipo de evento. De esta manera 34
no solamente podíamos decir qué fecha y a qué hora se había ejecutado el evento sino que además podríamos decir qué patrón se había ejecutado, si el evento era un BehaviourPatternExecution o qué usuario había ejecutado un UserAction. Las consultas SPARQL que permiten recuperar la información son: SELECT ?date ?time ?expaname WHERE { ?event rdf : type pros : BehaviourPatternExecution . ?event pros : date ?date . ?event pros : time ?time . ?event pros : executedPattern ?expa . ?expa pros :name ?expaname . FILTER (? date = xsd : date ("2010 − 08 − 23") ) . } ORDER BY DESC (? date ) DESC (? time ) Cuando queríamos recuperar los eventos de un día en concreto (fechas en formato ingles yyyy-mm-dd) SELECT ?date ?time ?expaname WHERE { ?event rdf : type pros : BehaviourPatternExecution . ?event pros : date ?date . ?event pros : time ?time . ?event pros : executedPattern ?expa . ?expa pros :name ?expaname . FILTER ((? date < xsd : date ("2010 − 08 − 24") ) && (? date > xsd : date ("2010 − 08 − 18") ) ) . } ORDER BY DESC (? date ) DESC (? time ) Cuando queríamos recuperar de un rango de días. Como se puede observar, el SPARQL es un lenguaje parecido al SQL. En el SELECT indicamos los datos que queremos recuperar. En la cláusula 35
WHERE indicamos cómo se accede a esos datos. Por ejemplo en la consulta anterior, en la primera condición del WHERE estamos indicando que queremos recuperar una Instancia cuyo tipo sea un BehaviourPatternExecution. En la segunda, tercera y cuarta condición estamos recuperando propiedades de ese individual. Las dos primeras propiedades son de tipo básico (date y time) la tercera hace referencia a una instancia de otra clase (ExecuttedPattern) en la última condición del WHERE accedemos a esa instancia y recuperamos su nombre. En el WHERE se pueden indicar ltros, en nuestro caso hemos puesto un ltro para que los eventos recuperados estén entre dos fechas. Por último con la cláusula ORDER BY se pueden ordenar los resultados. Hay otros tipos de cláusulas aunque son menos corrientes, por ejemplo en la consulta anterior si un evento no tuviera un ExecuttedPattern no saldría en el resultado de la consulta (o si no tuviera la fecha o la hora a la que se ha ejecutado), si un dato fuera opcional que estuviese o no estuviese se podría indicar mediante la cláusula OPTIONAL. Una vez añadidos en al API las funciones necesarias para poder recuperar los cuatro tipos de eventos se paso a generar las clases DAO correspondientes. Por último se pasó ha crear un BEAN parecido al de Estado Actual pero que ahora tuviese la información histórica. Teniendo en cuenta: Para las fechas se ha usado una instancia de la clase Calendar de Java Para convertir la fecha a formato inglés se ha usado la clase java.SQL.Date cuyo método toString devuelve la fecha en formato inglés. Con el método Calendar.add podíamos añadir o restar días al Calendar, de esta manera no hay que preocuparse por el cambio de mes o de año cuando buscas en un rango de días. El siguiente fragmento de código muestra una parte del BEAN Calendar cal= Calendar . getInstance () ; 36
ArrayList<Map<String , String>> behaviourpatterns ; TreeNodeBase treebehaviourpatterns = new TreeNodeBase(" BehaviourPatterns" , "Behaviour Patterns Execution" , false ) ; / ∗ Today ∗ / TreeNodeBase treebehaviourpatternstoday = new TreeNodeBase("Today" , "Today" , false ) ; behaviourpatterns= new BehaviourPatternDAO( lb . getApi () , new java . sql . Date( cal . getTime () . getTime () ) . toString ()).getBehaviourpatterns(); for ( int i = 0; i<behaviourpatterns . size () ; i++) { Map<String , String> dato = behaviourpatterns . get ( i ) ; treebehaviourpatternstoday . getChildren () . add( new TreeNodeBase("Event" , " Date : "+dato . get ("date")+" "+dato . get ("time") . substring (2)+" Executed Pattern : "+dato . get ("expaname") , false ) ) ; } treebehaviourpatterns . getChildren () . add( treebehaviourpatternstoday); / ∗ yesterday ∗ / cal . add( Calendar .DAY_OF_YEAR, − 1); TreeNodeBase treebehaviourpatternsyesterday = new TreeNodeBase("Yesterday" , "Yesterday" , false ) ; behaviourpatterns= new BehaviourPatternDAO( lb . getApi () , new java . sql . Date( cal . getTime () . getTime () ) . toString 37
()).getBehaviourpatterns(); for ( int i = 0; i<behaviourpatterns . size () ; i++) { Map<String , String> dato = behaviourpatterns . get ( i ) ; treebehaviourpatternsyesterday.getChildren(). add( new TreeNodeBase("Event" , " Date : "+dato . get ("date")+" "+dato . get ("time") . substring (2)+" Executed Pattern : "+dato . get ("expaname ") , false ) ) ; } treebehaviourpatterns . getChildren () . add( treebehaviourpatternsyesterday); cal . add( Calendar .DAY_OF_YEAR, 1) ; / ∗ Last Week ∗ / String dateup= new java . sql . Date( cal . getTime () . getTime () ) . toString () ; cal . add( Calendar .DAY_OF_YEAR, − 7); String datedown= new java . sql . Date( cal . getTime () . getTime () ) . toString () ; ; behaviourpatterns= new BehaviourPatternDAO( lb . getApi () , dateup , datedown) . getBehaviourpatterns () ; TreeNodeBase treebehaviourpatternslastweek = new TreeNodeBase("LastWeek" , "Last Week" , false ) ; for ( int i = 0; i<behaviourpatterns . size () ; i++) { Map<String , String> dato = behaviourpatterns . get ( i ) ; treebehaviourpatternslastweek.getChildren().add ( new TreeNodeBase("Event" , " Date : "+dato . 38
get ("date")+" "+dato . get ("time") . substring (2)+" Executed Pattern : "+dato . get ("expaname ") , false ) ) ; } treebehaviourpatterns . getChildren () . add( treebehaviourpatternslastweek); cal . add( Calendar .DAY_OF_YEAR, 7) ; / ∗ Last Month ∗ / cal . add( Calendar .MONTH, − 1); datedown= new java . sql . Date( cal . getTime () . getTime () ) . toString () ; behaviourpatterns= new BehaviourPatternDAO( lb . getApi () , dateup , datedown) . getBehaviourpatterns () ; TreeNodeBase treebehaviourpatternslastmonth = new TreeNodeBase("LastMonth" , "Last Month" , false ) ; for ( int i = 0; i<behaviourpatterns . size () ; i++) { Map<String , String> dato = behaviourpatterns . get ( i ) ; treebehaviourpatternslastmonth.getChildren(). add( new TreeNodeBase("Event" , " Date : "+dato . get ("date")+" "+dato . get ("time") . substring (2)+" Executed Pattern : "+dato . get ("expaname ") , false ) ) ; } treebehaviourpatterns . getChildren () . add( treebehaviourpatternslastmonth); cal . add( Calendar .MONTH, 1) ; 39
Figura 7: Devices 3.9. Otros aspectos considerados Aparte de lo comentado anteriormente durante el desarrollo de este Proyecto Final de Carrera se han tenido en cuenta otras cuestiones durante la implementación. Como se ha dicho en la sección 3.1 la clase User contiene el login y el password de los usuarios que tienen que acceder a la aplicación web (Hay partes de la aplicación que están restringidas a los usuarios). Para el login se ha creado un BEAN (LoginBEAN.java) que es el que se encarga de decir a la aplicación si hay un usuario conectado y quién es ese usuario. Utilizando el BEAN y la librería JSTL podemos saber si hay un usuario conectado y si no lo hay avisarle y evitar que entre en las zonas restringidas de la aplicación. En el LoginBean se encuentra la información del usuario, 46
ésta es necesaria dado que en el Estado Actual se usa esta información para mostrar solamente los datos del usuario que está conectado y no los datos de otro usuario de la aplicación. Uno de los problemas ha sido poder acceder a los BEANs desde JSTL dado que JSTL y JSF son dos tecnologías diferentes. Para acceder a una variable en JSTL se usa la siguiente sintaxis ${variable} mientras que para acceder a JSF se usa #{variable}. Algunos de los BEANs de la aplicación se van en la variable session (scopesession) de esta manera dado que desde JSTL se puede acceder al scopesession siguiendo navegando a través de la session logramos acceder al BEAN. ${sessionScope . loginBean . connected} Durante las primeras pruebas nos dimos cuenta que crear una nueva instancia del API_OWL cada vez que se quería hacer una consulta hacía que la aplicación fuera excesivamente lenta (El tiempo de crear una instancia es menor de medio segundo, pero si durante la carga de una página se creaban 10 o incluso 20 instancias cada vez que se quería leer información la página tardaba bastante en cargar). La solución fue añadir la instancia del API_OWL a un BEAN del tipo session para reutilizarlo y no tener que crearlo siempre. Finalmente se decidió añadirlo al LoginBEAN, de esta manera cuando un usuario se loguea a la aplicación crea su instancia del API_OWL y la reutiliza para todas las consultas. Para solucionar el problema en el Estado Actual de qué secciones se tienen que mostrar (si hay que mostrar los servicios ordenados por localización o ordenados por categoría) se creó un BEAN de tipo session en el que tuviera las preferencias del usuario que está conectado. La razón de hacer un bueno BEAN y no reutilizar por ejemplo el BEAN de login es simplicar y dividir para que la aplicación sea más fácil de ampliar en el futuro. 47
4. Interfaz de Usuario El Proyecto Final de Carrera, tal y como se ha comentado anteriormente, consiste en mostrar información sobre una sistema inteligente. Se ha elegido una tecnología web dado que de esta manera el usuario puede acceder a la aplicación desde cualquier lugar. El la gura 8 se puede observar como queda la página de la información del sistema. En la parte izquierda de la página, como se ha explicado en la sección 3.6, se muestra la información actual del sistema. El usuario puede ver los servicios de la página ordenados por localización (por defecto) o por categoría. También puede compobar las propiedades del entorno y las temporales. Por último el usuario puede comprobar sus datos, como los datos personales o las preferencias que tiene. En la parte derecha de la misma se encuentra la parte de hístorico, como se ha comentado en la sección 3.7 consta de dos secciones. El árbol superior muestra el histórico de eventos del sistema, como se puede comprobar en la imagen los eventos están agrupados por tipo. A continuación se pueden seleccionar, utilizando el calendario, los eventos de cualquier día en concreto, aunque no se puede poner fechas futuras. 48
Figura 8: System Information En la gura 9 se muestra el estado nal de la página de estadísticas. En esta sección se puede observar todas las grácas comentadas que se han realizado en el Proyecto Final Carrera, En la gura se ven las grácas de Eventos y la de última semana, para más información sobre estas grácas y otras adicionales se puede consultar la sección3.8. 49
Figura 9: Statistics 50
5. Instalación Para poner en marcha la aplicación se necesita un servidor web que soporte Java. La aplicación puede funcionar en distintos servidores de aplicaciones (Tomcat, jBoss ...). A continuación se va a describir los pasos necesarios para utilizar para usar la aplicación junto a Tomcat. 1. Tomcat necesita tener la máquina virtual instalada en el sistema. 2. Una vez instalada la máquina virtual procedemos a crear la variable de entorno JAVA_HOME poniendo como valor la ruta de instalación de Java. 3. Hay que añadir al PATH la ruta JAVA_HOME/bin 4. Copimos el archivo war a la carpeta TOMCAT/webapps 5. Ejecutamos en la carpeta TOMCAT/bin el archivo startup.bat si estamos en un sistema operativo Windows o startup.sh si estamos en Linux. Cuando sale un mensaje del estilo Server startup in 2500ms indica que el servidor esta ya funcionando. Se puede acceder a la aplicación mediante la dirección http://localhost:8080/PFC 51
6. Conclusiones En este Proyecto Fin de Carrera se ha desarrollado un portal web dinámico para mostrar información sobre un entorno inteligente intentando que cubra todas las necesidades del usuario. El portal que se ha desarrollado sirve para mostrar toda la información relevante para el usuario. Al ser una aplicación web esta información se podría consultar desde cualquier parte, esto permite al usuario saber en cada momento cual es el estado del entorno inteligente. También se ha creado un completo histórico de los eventos que han ocurrido en el entorno inteligente, de esta manera el usuario puede ver, de forma cómoda los eventos ocurridos en los últimos días aunque también tiene la oportunidad de ver los eventos que se ejecutaron en cualquier día en concreto. De esta manera el usuario puede consultar los cambios que ha habido en el entorno inteligente, por ejemplo, si estuviésemos en un dominio de casas domóticas prodríamos comprobar en vacaciones si se ha regado el césped. Por último, se ha creado una sección el que el usuario puede ver de manera gráca el porcentaje de eventos que hay de cada tipo en el sistema y la cantidad de eventos de cada tipo que se han ejecutado en el sistema. El Proyecto Final de Carrera me ha permitido aprender sobre las necesidades que puede tener los sistemas pervasivos además que ha servido para aprender nuevas tecnologías como JSF, OWL, SPARQL que me pueden servir en el futuro profesional. Hay que destacar que este Proyecto Final de Carrera es un subproyecto de uno más grande sobre sistemas pervasivos que se está llevando a cabo en el Centro de Investigación de Métodos de Producción de Software (ProS) de la Universidad Politécnica de Valencia. 52
Referencias [1] SERRAL, E., PÉREZ, F., VALDERAS, P. y PELECHANO, V. Adaptation to User Behaviour by Evolving Systems through Models at Runtime. Submitted to Information and Software Technology, Marzo 2010. [2] SERRAL, E., VALDERAS, P. y PELECHANO, V. Supporting Runtime System Evolution to Adapt to User Behaviour, in the 22nd International Conference on Advanced Information Systems Engineering (CAiSE'10). 2010. Volume 6051 of Lecture Notes in Computer Science. pp. 378-392. ISBN: 978-3-642-13093-9 [3] THESERVERSIDE. Your Enterprise Java Community [en línea] [fecha consulta 15 07 2010] Disponible en <http://www.theserverside.com/>. [4] YOSHTEC KB. A small knowledge base [en línea] [fecha consulta 17 07 2010] Disponible en <http://wiki.yoshtec.com/java-owl-api>. [5] JENA. A Semantic Web Framework for Java [en línea] [fecha consulta 05 07 2010] Disponible en <http://jena.sourceforge.net/>. [6] JASTOR. Typesafe, Ontology Driven RDF Access from Java [en línea] [fecha conshttp://myfaces.apache.org/ulta 05 08 2010] Disponible en <http://jastor.sourceforge.net/>. [7] ECLIPSE. Web de la empresa [en línea] [fecha consulta 05 08 2010] Disponible en <http://www.eclipse.org/>. [8] APACHE MYFACES. JavaServers [en línea] [fecha consulta 07 08 2010] Disponible en <http://myfaces.apache.org/>. [9] JFREECHART. Java [en línea] [fecha consulta 08 08 2010] Disponible en <http://www.jfree.org/jfreechart/>. 53
[10] ORACLE. Recurso de la empresa [en línea] [fecha consulta 10 08 2010] Disponible en <http://www.oracle.com/technetwork/java/javaee/javaserverfaces139869.html> y en <http://java.sun.com/blueprints/enterprise/index.html>. 54