martes, 1 de marzo de 2011
Desarrollando por hobbie en N900
En los anteriores modelos de celulares que tuve, disponía de la plataforma Java ME (aprovechando que me gusta jugar un poco con desarrollos en Java) o Symbian. Aquí puedo hacer programas en C, C++, GTK, python, ruby, Qt y Java SE embedded. Esta última es la que me gusta más, por supuesto, porque puedo aprovechar entornos de desarrollo como NetBeans / Eclipse para hacer programas complejos en Java SE y pasarlos sin problemas al celular.
Para iniciar con Java en Nokia N900 primero debe instalarse OpenJDK que puede ser bajada e instalada por apt-get o ir a la página de Oracle para bajar la versión Java SE for Embedded 6 Update 21 General Availability for Linux (ARM).
Ya probé con OpenJDK y anda perfect, esto será muy divertido para mi.
miércoles, 20 de octubre de 2010
Java ME y DB Objects III: Buscadores y Resultados
Ya habiamos diseñado a un objeto genérico DataManager para el control del ciclo de vida de los objetos persistentes. En él, se usaban a los buscadores y a los resultados, como auxiliares para poder gestionar a los objetos de datos DataObject.
El DataFinder debería ser un objeto que pueda recoger las definiciones de búsqueda y pueda realizar la comparación entre objetos de datos DataObject. Java ME dispone de dos objetos para definir filtros (criterios de selección de objetos) y comparadores. El prototipo de un DataFinder sería asi:
package com.saphi.mdba;
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordFilter;
public interface DataFinder {
public RecordFilter getFilter();
public RecordComparator getComparator();
public boolean isKeepUpdated();
}
El DataResult seria similar a un objeto ResultSet de Java ODBC (especificación de Java SE para conexión uniforme de programas Java a base de datos relacionales). Bueno copiando un poco esta misma filosofía, el DataResult sería como una colección o lista de objetos DataObject, con ciertos métodos para operar sobre él como ordenamiento de objetos, obtención de algún atributo de algún objeto DataObject, etc. El prototipo quedaría asi:package com.saphi.mdba;
import java.util.Enumeration;
public interface DataResult {
public boolean exist(int key);
public boolean exist(DataObject dataObject);
public boolean isEmpty();
public Enumeration dataObjects();
public Enumeration keys();
public DataObject get(int key);
public DataObject dataObjectAt(int pos);
public void sort();
public void sort(int col);
public void sort(int[] col);
public int count();
public Object[][] getValues();
}
Con esto quedaria completo el objeto DataManager expuesto anteriormente en el primer post:package com.saphi.mdba;
import javax.microedition.rms.RecordStoreException;
public interface DataManager {
public Class getDataObject();
public String getRecordStoreName();
public DataObject getInstance();
public DataObject findByKey(int key) throws RecordStoreException;
public DataResult find() throws RecordStoreException;
public DataResult find(DataFinder finder) throws RecordStoreException;
}
En resumen, se tiene un modelo que proporciona un gestor (DataManager) para la administración completa del ciclo de vida de objetos de datos (DataObjet), un buscador genérico (DataFinder), que también contiene un filtro para la búsqueda de datos y un resultado de la búsqueda (DataResult) que contiene todos los objetos de datos del resultado de las consultas (note los métodos de ordenamiento).Con esto ya tenemos la base para realizar la implementación de los objetos de datos. En el próximo post, desarrollaré una implementación básica muy útil que facilitará aún más la aplicación de estos conceptos. Hasta luego.
jueves, 11 de marzo de 2010
DB Objects: Debí comenzar por aquí
Bueno antes de complicarme más y más con estas ideas y código Java, mejor explicaré ahora el concepto de lo que se buscó para dicho propósto. Entonces, va de nuevo, y olvídense por un momento lo expuesto en el post JavaME y DBObjects (luego le encontraremos más sentido).
Todo comenzó con la necesidad de tener un mecanismo de almacenamiento de datos en celulares. Sería simple si se pudieran crear objetos en Java y que éstos ya puedan almacenarse en algún repositorio de datos con una simple orden "guardar":
public class Contacto {La técnica para guardar los datos del contacto podría ser tomar todos sus atributos y concatenarlos, luego asignarles un código único y guardarlo en el repositorio.
public String nombre;
public String telefono;
public String correo;
public String guardar() {
// .. aquí estaria toda la lógica
// para guardar al contacto en el
// celular.
}
}
Contacto 1:
- Nombre: Juan Pérez
- Teléfono: 987524411
- Correo: juan.perez@correo.net
Contacto 2:
- Nombre: María Sánchez
- Teléfono: 993555720
- Correo: m.sanchez.t@ien.com
public class Mensaje {
public String remitente;
public String contenido;
public String[] contactos;
public String guardar() {
// .. aquí estaria toda la lógica
// para guardar el mensaje
}
}
Mensaje 1:
- Remitente: Esteban Salas
- Contenido: Hoy habrá una fiesta en casa de Pedro a las 7:00 pm
- Contactos: Juan Pérez, María Sánchez
Mensaje 2:
- Remitente: Esteban Salas
- Contenido: Inviten a Elena, Marcos y Silvia. ¡Nos vemos!
- Contactos: Juan Pérez, María Sánchez
En este caso la técnica a usar para almacenar el mensaje en el celular sería la misma, es decir, juntar todos los atributos del mensaje, concatenarlos, asignarles un código único y guardalo en el repositorio de datos.
Entonces para almacenar al contacto, la lógica del método "guardar" podría ser:
public class Contacto {De la misma forma con el mensaje:
public String nombre;
public String telefono;
public String correo;
public String guardar() {
String contacto = nombre + "" +
telefono + "" +
correo;
// Genera clave única
String id = UKG.getKey(contacto);
// Convierte al contacto en bytes
bytes[] data = contacto.toBytes[];
...
// Procedimiento que guarda los bytes
}
}
public class Mensaje {
public String remitente;
public String contenido;
public String[] contactos;
public String guardar() {
String mensaje = remitente + "" +
contenido;
//Concatena a todos los contactos destino
for (int i = 0; i < contactos.lenght; i++)
mensaje = mensaje + "" + contactos[i];
// Genera clave única
String id = UKG.getKey(mensaje);
// Convierte al mensaje en bytes
bytes[] data = mensaje.toBytes[];
...
// Procedimiento que guarda los bytes
}
}
Si el mecanismo es el mismo, se podría crear un método general que lea cada atributo del objeto, los concatene, los convierta en bytes, genere la clave única y almacene al objeto. Ese método ya no tendría que ser implementado en cada objeto de dato, pues siempre será de la misma forma. ¿Sucedería lo mismo con la carga de objetos que ya estan en el repositorio de datos?, es decir, ¿se podría crear un método general que permita leer bytes del celular y traerlos como objetos para las aplicaciones de celulares? La respuesta es si.
Entonces es correcto pensar en una librería que permita abstraer todas esas lógicas de tratamiento de datos para que sólo nos podamos concentrar en la lógica de la aplicación. Claro que si, por ejemplo los objetos de datos se crearían como hijos de uno padre que ya tenga implementado el método guardar. Sería más simple como se muestra a continuación:
public class Contacto extends ObjetoDato {
private String nombre;
private String telefono;
private String correo;
// Ya no es necesario, hereda del padre
// public String guardar() {
// }
}
public void guardarContactoEjemplo() {
Contacto contacto = new Contacto();
contacto.nombre = "Juan Pérez";
contacto.telefono = "987524411";
contacto.correo = "juan.perez@correo.net";
// Método mágico para guardar los datos
contacto.guardar();
}
Bueno, esta es precisamente la filosofía del desarrollo: crear una capa que abstraiga la lógica de operaciones de datos usando RMS de Java ME.
miércoles, 10 de marzo de 2010
Uso de Notepad++
Bueno, en este post, sólo quería complementar lo escrito en el artículo Pseu4 de este blog, que habla acerca del lenguaje de pseudocódigo, con una implementación especifica para Notepad++. Básicamente después de instalar el Notepad++ (ya sea en binario zip o con el instalador), se debe colocar el archivo userDefineLang.xml en la carpeta raíz del mismo, reiniciar y listo.
En lo personal yo uso el estilo Plastic Code Wrap, porque tiene fondo oscuro y desgasta menos la vista y tipo de letra Arial Monospace for SAP 9 o Dina 9. Menu Configurar/Configurador de estilo.
Una vez configurado el estilo, en el menu Lenguaje se puede aplicar el tipo lenguaje que se usará. Por ejemplo en la imagen se escribió un código como texto, luego aplicando Lenguaje/Pse4 se tiene la diferenciación de colores y los folders.


Bueno eso es todo por hoy.
martes, 9 de marzo de 2010
Java ME y DBObjects: Persistencia para aplicaciones de celulares
Lo que explicaré ahora será un poco la definición y arquitectura de ese desarrollo. Básicamente la idea era contar con unos objetos que encapsularan la lógica de almacenamiento y recuperación de datos pero usando Java ME, de manera similar como existe ahora en la plataforma Java EE a través de la tecnología EBJ.
La otra premisa de este desarrollo es que RMS utiliza datos en bytes para almacenar la información (Java EE tiene sus propios mecanismos de persistencia de objetos pero para éstas aplicaciones se suele usar una base de datos como Oracle o MySQL).
Primer Paso:
Contar con un objeto de datos que pudiera ser persistente, sea único e identificable, modificable en sus atributos y estado, y, que finalmente pueda ser eliminado del repositorio de datos. El resultado es la definición del objeto DataObject:
package com.saphi.mdba;
public interface DataObject { public int getKey(); public boolean isStored(); public int store() throws RecordStoreException; public void remove() throws RecordStoreException; public void set(byte[] data); public byte[] get(); public Object[] getAttributeValues(); public String getRecordStoreName(); }Segundo Paso:
Lo siguiente es contar con un objeto que administre el ciclo de vida de los objetos de datos, es decir, que nos permita crear, buscar y cargar objetos de datos. Este objeto administrador debe estar enlazado con su objeto de datos de forma que sólo sirva para éste. También es necesario un mecanismo de búsqueda por su clave única o por un conjunto de criterios como el valor de sus atributos. El resultado de la búsqueda podría traer varios objetos de datos, por tanto todos ellos deben manejarse dentro de una colección. Este segundo objeto, más complejo que el anterior, tiene la siguiente definición a través de DataManager:
package com.saphi.mdba; import javax.microedition.rms.RecordStoreException;
public interface DataManager { public Class getDataObject(); public String getRecordStoreName(); public DataObject getInstance(); public DataObject findByKey(int key) throws RecordStoreException; public DataResult find() throws RecordStoreException; public DataResult find(DataFinder finder) throws RecordStoreException; }Como ven en este punto es necesario 2 objetos adicionales DataResult y DataFinder, uno para depositar los objetos de datos producto de la búsqueda (DataResult) a través de un objeto buscador (DataFinder). En el siguiente post, desarrollaré estos dos objetos para completar la definición de DataManager.
En resumen, hasta ahora sólo hemos creado un objeto que representa a la entidad de dato que queremos se guarde en algún repositorio (DataObject) y otro objeto que nos permite controlar el ciclo de vida de los objeto de datos (DataManager).
jueves, 4 de marzo de 2010
Pseu4
Para su aplicación también he creado una definición de lenguaje propio en el conocido editor Notepad++, en el cual ya se incorporan manejo de folders, palabras claves, signos, estructuras de programa y sentencias de base de datos.
En si el propósito de este lenguaje es poder definir de una manera natural muchas lógicas que deberían seguir las especificaciones técnicas de nuestros productos de software. Las palabras usadas y la lógica se asemejan un poco a ABAP4 y Java, pero esto en realidad no importa mucho, lo que si importa es que se puede definir lógicas estructuradas de fácil comprensión y que permiten aclarar las interacciones entre los analistas funcionales y técnicos.
Otro a porte es que está en español y cada uno de ustedes puede extender y usar libremente segun lo requieran. También soporta construcciones de lógica secuencial y orientada a objetos.
Aquí les paso un ejemplo de cómo uso Pseu4 para especificar una función que finalmente será traducido a ABAP.
Espero les guste y sobretodo les pueda ser útil en algún momento. Abajo les dejo el código de Pseu4 para subirla a Notepad++, incluye las versiones de colores Xcode y CO+. También está una versión de ABAP4 de Franco Capetta que incorpora folders y nuevos simbolos.
Definición Pseu4, XCode y más: http://www.megaupload.com/?d=ESK8MJH0