sábado, 26 de abril de 2008

Anotacions sobre Hibernate

1. Guía hacia Hibernate : http://www.javahispano.org/contenidos/es/guia_del_autoestopista_a_hibernate_/

¿Que es Hibernate?

Hibernate ofrece la Persistencia Relacional para Java, que para los no iniciados, proporciona unas muy buenas maneras para la persistencia de sus objetos de Java a y desde una base de datos subyacente. Más que ensuciar con SQL tus objetos y convertir consultas a y desde los objetos de primera magnitud, Hibernate puede preocuparse de todo ese maremágnum por ti. Tú utilizas solamente a los objetos, Hibernate se preocupa del SQL y de que las cosas terminan en la tabla correcta.

El Proceso Del Desarrollo.

Hay varias maneras de acercarse al desarrollo con Hibernate. Aquí está el que estamos utilizando nosotros hoy, porque es probablemente el más simple de entender:

1. Crea tu tabla del SQL para guardar tus objetos persistentes.
2. Crea un JavaBean que represente ese objeto en código.
3. Crea un archivo de mapeo de manera que Hibernate sepa qué características del bean se mapean a que campos del SQL.
4. Crea un archivo de propiedades de manera que Hibernate conozca la configuración JDBC para acceder a la base de datos.
5. Comienza a usar el Hibernate API.

Paso 1: Escribir el SQL

** En el meu cas he procedit al disseny de la base de dades de forma manual, i després el PHPMYADMIN ha procedit a la creació de les corresponents taules.

**Les taules a tractar són les següents : Grup, Pertany, Usuari, Esdeveniment

**Per el cas dels usuaris, tot i que s'ha d'aplicar a tota la resta

Cuando tenemos un montón de Users en memoria, necesitaremos una clase Java para que los contenga. Hibernate trabaja vía reflection en los métodos de get/set de los objetos, así que necesitaremos "bean"-ificar los objetos que deseamos persistir.

** Per tant necessitem un Usuari.java amb les funcions de get/set per a cada paràmetre de la taula d'usuaris.

Paso 3: Escribir el archivo de Mapeo

Ahora ya hemos conseguido nuestra tabla del SQL, y el objeto de Java que va a mapearse con ella. Todavía necesitamos una manera de decir a Hibernate cómo mapear uno con otro. Esto se logra a través de un archivo de mapeo. La manera más limpia (la más mantenible) es escribir un archivo de mapeo por objeto.

** Exemple del tros d'arxiu de mapeig (el propi de la meva taula d'usuris):

Etiqueta class. Aquí mapeamos el nombre de la clase (en el paquete del *usuari*) a la tabla de usuarios en nuestra base de datos.

Etiquetas property. Un vistazo rápido mostrará que aquí es donde se está haciendo el trabajo importante. El atributo name es la característica en nuestro Bean, y column es el nombre del campo en nuestra base de datos. El atributo type es opcional (Hibernate utilizará reflection para conjeturar el tipo si tu no lo pones).

**Només he ficat una de totes les possibles.

etiqueta id. Quizás hayas sospechado que esta etiqueta tiene algo que ver con el mapeo de la clave primaria de la tabla. Tienes razón. La sintaxis de la etiqueta id es muy similar a la de las etiquetas de características que acabamos de ver. Mapeamos la característica del Bean (name) al campo de la base de datos(column). La etiqueta embebida del generador le dice a Hibernate cómo debe producir la clave primaria (es bastante divertido que Hibernate te genere una, del tipo prefieras, pero necesitaras decirle cómo).

Paso 4: Crear un archivo con las características para su base de datos

< style="font-family:verdana;">
< package="edu.upc.pfc.eci.negoci">
< name="Usuari" table="usuari">
< name="Id" type="string" column="userid">
< class="sequence">
< /generator>

< name="Userlogin" column="userlogin" type="string" null="true" length="255">

< /property>
< /id>
< /class>
< /hibernate-mapping>


Todavía no le hemos dicho a Hibernate dónde encontrar nuestra base de datos. La manera más directa es proporcionar a Hibernate un fichero de las características, con los ajustes para las secuencias de la conexión, las contraseñas, etc. Si llamas a este archivo hibernate.properties y lo pones en el classpath, Hibernate lo tomará automagicamente (sic). El fichero tendría un aspecto como este:

       hibernate.connection.driver_class = org.gjt.mm.mysql.Driver
hibernate.connection.url = jdbc:mysql://localhost/testdb
hibernate.connection.username = gsmith
hibernate.connection.password = sesame

Si has utilizado JDBC, éste te resultara familiar. En el ejemplo de arriba un driver de mysql, se conecta con la base de datos testdb en localhost, y utiliza el usuario y contraseña proporcionados. Hay un montón más de características que puedes ajustar para determinar cómo Hibernate tiene acceso a tu base de datos. De nuevo, consulta la documentación para más información detallada.

Paso 5: Comience a hacer magia con Hibernate

Hacer uso de Hibernate en tu código fuente es bastante directo. Ahí va la versión reducida:

  1. Cree un objeto Datastore

  2. Dile al Datastore el tipo de objetos que deseas almacenar

  3. Crea una sesión a la base de datos de tu elección

  4. Carga, guarda y consulta tus objetos

  5. flush() tu sesión de vuelta a la base de datos

Primero, creamos el objeto de Datastore...

El objeto Datastore tiene conocimiento de todos los mapeos que existen entre los objetos de Java y la base de datos.

        Datastore ds = Hibernate.createDatastore();
ds.storeClass(User.class);

Esto asume que tienes un User.hbm.xml en el mismo directorio que la clase user. Si decides llamar a tu archivo de otra manera, utiliza:

 ds.storeFile("MyMappingFile.hbm.xml")

Entonces, crea un objeto de sesión...

El objeto de sesión representa una conexión a su base de datos. Puedes proporcionar a Hibernate una sesión de JDBC que hayas creado a mano, pero soy perezoso, así que solo voy a proporcionarle a Hibernate el archivo de propiedades, y dejar que haga el trabajo por mí.

        // Then build a session to the database
SessionFactory sf = ds.buildSessionFactory();
// or supply a Properties arg
Session session = sf.openSession();

He llamado a mi archivo de propiedades hibernate.properties y lo he puesto en mi classpath, pero si has llamado al tuyo de manera diferente (o quieres crear las propiedades en el código), entonces necesitaras proporcionar tu propio objeto de propiedades a buildSessionFactory().

¡Después carga, guarda y consulta tus objetos!...

Ahora solo tienes que usar los objetos de una manera Java. ¿Quieres almacenar un nuevo usuario en la base de datos? Seria algo así:

 // Create new User and store them the database 
User newUser = new User();
newUser.setID("joe_cool");
newUser.setUserName("Joseph Cool");
newUser.setPassword("abc123");
newUser.setEmailAddress("joe@cool.com");
newUser.setLastLogon(new Date());

// And the Hibernate call which stores it
session.save(newUser);

Como puedes ver, la gran ventaja de Hibernate es el poco código adicional a emplear. La mayor parte del tiempo solo te preocupas de tus objetos de negocio, y haces una sola llamada a Hibernate cuando todo esta preparado.

Pongamos por caso que deseas recuperar un objeto y sabes el UserID del usuario (ej. durante un proceso de la conexión a su sitio). Con una unica línea, pasando la clave ya lo tienes :

    newUser = (User) session.load(User.class, "joe_cool");

El objeto usuario que has recuperado esta vivo! Cambia sus propiedades y se guardara en la base de datos en el próximo flush().

Incluso mejor , puedes consultar tu tabla y obtener una java.util.List de objetos vivos. Prueba con algo como esto:

List myUsers = session.find("from user in class dbdemo.User");

if (myUsers.size() > 0) {
for (Iterator i = myUsers.iterator(); i.hasNext() ; ) {
User nextUser = (User) i.next();
System.out.println("Resetting pass: "+ nextUser.getUserName());
nextUser.setPassword("secret");
}
}else {
System.out.println("Didn't find any matching users..");
}

Esta consulta devuelve toda la tabla . Normalmente querrás mucho mas control (ej. From user in class dbdemo.User where userID tenga algún valor especifico),de manera que harás algo como esto:

        List myUsers = session.find("from user in class dbdemo.User where user.ID = ?","joe_cool", Hibernate.STRING);

Hay una gran abundancia de opción de consulta en la documentación, pero esto te da una idea de lo que Hibernate puede ofrecerte.

...Y finalmente flush() tu session

De vez en cuando tu sesión de Hibernate se hará flush() a si misma para mantener una correcta sincronización entre la BD y tus objetos en Memoria. Puedes querer liberar la conexión JDBC que Hibernate esta usando para lo cual normalmente harás:

        // close our session and release resources
session.flush();
session.close();
** tot això amb el plugin per eclipse està molt simplificat :D

domingo, 9 de marzo de 2008

Casos d'ús provisionals

Llista dels casos d'ús especificats fins el moment

1. Sincronització automàtica
2. Sincronització manual.
3. Configuració
4. Entrada al sistema
5. Sortida del sistema
6. Alta d’usuari nou
7. Baixa disciplinària d’usuari
8. Baixa de l’usuari
9. Alta d’usuari existent
10. Eliminar usuari
11. Alta esdeveniment
12. Modificar esdeveniment
13. Eliminar un esdeveniment
14. Llista d’esdeveniments
15. Visualitzar esdeveniment
16. Creació d’un grup
17. Afegir usuari a un grup
18. Eliminar usuaris d’un grup
19. Modificació de grup
20. Eliminar grup
21. Llista d’esdeveniments

lunes, 11 de febrero de 2008

ToDo List!

Cosetes a fer:

1.- Definir els objectius del projecte.
Afagar l'última versió de l'informe de definició i redactar un o dos objectius que siguin resum dels que apareixen en aquell document. Aquests seran els GOALS. Per a cada goal, definir Purpose, Advantage i Measure, segons els documents que dels "Objectius Volere". També està al capítol 3 del "Mastering...".

2.- Fer l'anàlisi d'stakeholders.
Omplir la taula excel amb tota la informació que cal. Com més dades es col·loquin aquí, millor fet estarà l'anàlisi d'implicats. La taula està feta per a que només llegint els camps que ja estan omplerts a la plantilla i reflexionant un mica s'obté un anàlisi gairebé perfecte.

3.- Estudiar els exemples.
Mirar com estàn organitzats els documents d'exemple. Aquesta hauria de ser la estructura d'una part de la memòria. L'índex de la memòria es fixarà en una propera reunió, però inclourà bona part d'aquest document. Dels caos d'ús en parlarem més endavant.

4.- Preparació de l'estudi de requisits.
Mira com està muntada la "snowcard" i estudiar com estan organitzats els requisits segons el mètode Volere. A partir dels casos d'ús s'obtenen els requisits, d'una manera casi mecànica.

jueves, 7 de febrero de 2008

Consideracions visibilitat

Alguns telèfons mòbils ens permeten definir el tipus de sincronització que volem aplicar als esdeveniments que tenim emmagatzemats. Aquest tipus de sincronització no deixa de ser la visibilitat que volem que tinguin aquests, en el cas que abarca aquest PFC el factor de la visibilitat és importat ja que ens permet determinar qui volem que observi els nostres esdeveniments.

Per tant en el cas de que es determini la visibilitat des de el dispositiu mòbil podrem indicar que sigui pública o privada. I en el cas de que la visibilitat es determini des de la interficie web podrem escollir entre privada, pública o determinada.

Es considera visibilitat pública quan tots els usuaris tenen permisos per llegir aquesta informació. En el cas de ser privada només el usuari generador / propietari tindrà permisos sobre aquell esdeveniment. I finalment en el cas de ser determinada podrem determinar quin grup d'usuaris podran rebre la informació.

Cal tenir present que qui genera l'esdeveniment és qui té inicialment els permissos necessaris per a dur a terme qualsevol modificació. Ens podriem plantejar de en un futur determinar si s'els hi pot otorgar a determinats usuaris permisos per dur a terme les modificacions oportunes. Aquesta característica només seria viable des de la interficie web ja que no disposem de cap paràmetre al telèfon mòbil que ens ho permeti realitzar.


Per altre banda tenim que no tots els telèfons mòbils ens permeten determinar el tipus de visibilitat, per tant a no ser que s'afirmi el contrari tot esdeveniment que es generi al dispositiu serà enviat al servidor com a esdeveniment privat a no ser què es defineixi en el telèfon com a sincronització pública.

Si hi ha un camp que defineix la sincronització com a pública ens caldrà determinar quin és el paràmetre/tag que defineix que la sincronització és pública (i el mateix per la privada).

Quan des del dispositiu mòbil volem determinar que un esdeveniment és públic però no disposem de l'opció que ens permet determinar el tipus de visibilitat, tindrem que o bé generar el esdeveniment des de la interficie web i indicar el tipus de visibilitat o bé generar-lo des del dispositiu mòbil i després modificar els permissos de visibilitat des de l'interficie web. El mateix procediment caldrà seguir quan volguem que un esdeveniment tingui visibilitat determinada.

miércoles, 6 de febrero de 2008

Control d'Esdeveniments / Entrades

Fins ara per analitzar les dades que s'envien des del telèfon mòbil al servidor utilitzavem les generades per un dels exemples de la API JSR75 però si aquest tractament de dades el portem als telèfons mòbils reals ens podem trobar diferencies... diferencies que s'han de tenir presents a l'hora de dissenyar el model de dades de una part de l'especificació del projecte.

Per ara tenim que en els següents mòdels de telèfons mòbils els esdeveniments i els seus paràmetres poden ser:

NOKIA N-70

Tipus d'esdeveniments: Reunión
Memorándum
Aniversario (opció que directament no es contempla)

Parametres per a cada esdeveniment:

1. Reunión:
Asunto
Ubicación
Hora de inicio
Hora de finalización
Día de inicio
Día de finalización
Alarma
Repetición
Sincronización

2. Memorandum
Asunto
Día de inicio
Día de finalización
Sincronización


MOTOROLA Z8

Tipus d'esdeveniments: Cita
Rercordatorio
Cita todo el dia
Aniversario (opció que directament no es contempla)

1. Cita
Asunto
Fecha de inicio
Fecha de fin
Hora de inicio
Hora fin
Posición
Alarma
Repetir
Categoria
Moderador
Asistentes
Notas

2. Recordatorio
Asunto
Fecha
Hora
Posición
Alarma
Repetir
Categoria
Notas

3. Cita todo el día
Asunto
Fecha de inicio
Fecha de fin
Posición
Alarma
Repetir
Categoria
Moderador
Asistentes
Notas

Sony Ericsson W660i

Tipus d'esdeveniments: Cita

1. Paràmeteres:
Asunto
Hora Inicial
Duración
Recordatorio
Fecha Inicial

Nokia 6120

Tipus d'esdeveniments: Reunión
Memorandum
**La resta no ens interessa

1. Reunión:
Asunto
Ubicación
Fecha Inicio
Hora Inicio
Fecha Fin
Hora Fin
Tipo Alarma
Alarma (indicamos cuanto antes queremos que nos avise)

2. Memorandum:
Asunto
Fecha Inicio
Fecha Fin
Tipo Alarma
Alarma (igual que en el caso de reunión)
Hora

Nokia 6288

Tipus d'esdeveniments: Reunión
Llamar a
Memorandum
Nota de aviso
**La resta no ens interessa

1. Reunión
Asunto
Lugar
Fecha de inicio
Hora de inicio
Fecha de fin
Hora de fin
Tipo de alarma
Fecha de alarma
Hora de alarma
Repetir?
**En cas afirmatiu : Repetir indefinidamente

2. Llamar a
Nombre
Número de teléfono
Fecha
Hora
Tipo de alarma
Hora de alarma
Repetir?
**En cas afirmatiu : Repetir indefinidamente

3. Memorándum
Asunto
Fecha de inicio
Fecha de fin
Tipo de alarma
Fecha de alarma
Hora alarma
Repetir
**En cas afirmatiu : Repetir indefinidamente

4. Nota de aviso
Tema de nota de aviso
Fecha
Alarma
Hora de alarma
Repetir?
** En cas afirmatiu : Repetir indefinidamente



Hi ha camps comuns però cal analitzar com es tracten cadascun d'aquests camps.

Algú pot afegir el tractament que en fa el seu telèfon mòbil? Gracies!!


Plantejament : Cal dur a terme una sincronització de les notes d'avís? En un principi penso que les notes d'avís poden ser considerades iguals o similars als memorandums, caldria analitzar la diferència que s'observa entre ambdues.

miércoles, 30 de enero de 2008

Plantejaments

Parlant del projecte amb un amic ens han sorgit plantejaments com els que detallo a continuació.

1. Enviament de les dades del mòbil al servidor.

Cada vegada que es duu a terme la sincronització de dades necessitarem enviar els nous esdeveniments generats al servidor, per fer-ho en principi tenim un string que ens emmagatzema la informació a enviar. Aquesta informació està emmagatzemada amb els corresponents tags XML. De manera que si per a un esdeveniments no coneixem tots els seus paràmetres, només enviarem aquells coneguts amb els tags corresponents.

Fins ara tot sembla correcte, però si ens parem a pensar ens podem trobar de que estem enviant massa informació al servidor, per tant el paquet de dades és més gran per què cada tag apareix com a mínim dues vegades.

Una alternativa plantejada seria enviar les dades separades per comes en comptes de per tags. Ara tindríem que enviar una coma per cada paràmetre que enviem al servidor. De manera que si desconeixem una característica del esdeveniment en el seu lloc col·locarem una coma i el servidor ha de ser capaç de interpretar que aquell camp es troba buit. Per tant podríem formar el XML al servidor.

Al separar-lo per comes podem estar reduint a la meitat el nombre de dades a enviar.

Caldria tenir present possibles problemes de velocitat en la generació / tractament de arxius XML en el dispositiu mòbil.


2. Programació part del servidor

Fins ara tenia molt clara la idea de programar la part del servidor en PHP. No s'han analitzat en profunditat els temes d'arquitectura corresponents, però resultava interessant fer treballar dos llenguatges diferents. Però per altre banda ens trobem que el PHP no ens permet debugar.

Una alternativa seria fer-ho en Java, passaríem a treballar en el fons en el mateix llenguatge sols que aplicat a arquitectures hardware diferents. Tot hi que ens podem trobar que el tomcat ens doni problemes.

3. Gestió de la base de dades

Per ara hi ha tres possibles opcions, el que no implica que les tres siguin vàlides.

a. gestionar la base de dades "a pèl" a base de SQL
b. Propel
c. Hibernate


4. Gestió del tema de seguretat

S'han plantejat opcions com encriptació amb keypair i SSL...

5. Gestió de login

Cada vegada que un usuari es logegi tindrem que dur a terme una gestió. Una de les coses que ens pot ajudar a decidir entre PHP o JAVA seria l'existència de una API que ens permetés dur a terme la gestió d'aquest login.

Alguna idea més?

lunes, 28 de enero de 2008

Sincronització en el client casi enllestida

Fa una setmana que ja comença a tenir més bona pinta la part del client, és a dir, aquella que s'executarà en el telèfon mòbil. Per ara, cada vegada que des de la nostra aplicació escollim l'opció de sincronitzar s'ens genera un string que emmagatzema (per ara) tots els esdeveniments que tinguem emmagatzemats en l'agenda del dispositiu mòbil.

Aquest String serà el que enviarem al servidor, és a dir, al webservice. Per tant ara cal desenvolupar una petita part de servidor.

La part de servidor es desenvoluparà en PHP, per tal haig de montar un servidor que treballi amb extensions de SOAP.