lunes, 15 de diciembre de 2008

Programa para determinar la compañía de un movil (Chile)

Aprovechando el insomnio de la noche del sábado, me he puse a programar una pequeña aplicación java para el celular, en éste al ingresar un número telefónico me indica a qué compañía pertenece (en Chile), y con esto también me dejo de andar preguntado "oye de qué compañía es tu móvil ?":) .
Por ahí anda otra aplicación que hace lo mismo, pero no me permitía seleccionar el número de mi agenda :(
Bueno sin más aquí dejo programa, solo tienen que copiar el archivo ComChile.jar al móvil y ejecutarlo ahí.
Además adjunto el código fuente.
Cualquier crítica, sugerencia o comentario será bienvenido.

Descargar programa

Fuente

Acá la clase principal:
/*  ComChile v1.1
* ------------------
* Copyright (C) 2008, René Vielma M. renevielma@gmail.com.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

package pkg;


import java.io.IOException;
import java.io.InputStream;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


/**
* ComChile
* @author rene
*/
public class ComChile extends MIDlet implements ItemStateListener,CommandListener {

private Command salir, limpiar, about;
private Display display;
private Form formulario;
private TextField txt;
private Image imgClaro, imgMovistar, imgEntel;
private ImageItem imagenItem;

public ComChile() {

display = Display.getDisplay(this);

formulario = new Form("ComChile");

//Carga de imagen
try {
imgClaro = Image.createImage("/claro.jpg");
imgMovistar = Image.createImage("/movistar.jpg");
imgEntel = Image.createImage("/entel.jpg");
} catch (IOException e) {
e.printStackTrace();
}

salir = new Command("Salir", Command.EXIT, 1);
about = new Command("about", Command.HELP, 3);
limpiar = new Command("Limpiar", Command.OK, 0);
txt = new TextField("Número telefónico",null,20,TextField.PHONENUMBER);
imagenItem = new ImageItem(null,null ,Item.LAYOUT_CENTER,"no está la imagen",Item.BUTTON);

formulario.append(txt);

formulario.addCommand(salir);
formulario.addCommand(limpiar);
formulario.addCommand(about);
formulario.setCommandListener(this);
formulario.setItemStateListener(this);

}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}

protected void pauseApp() {}

protected void startApp() throws MIDletStateChangeException {
display.setCurrent(formulario);
}

public void commandAction(Command c, Displayable s) {

if (c.getCommandType() == Command.EXIT)
notifyDestroyed();

if(c == limpiar){
txt.setString("");
if(formulario.size() == 2)
formulario.delete(1);
}

if(c == about){
Alert alert = new Alert("About", "ComChile v1.1 autor: Rene Vielma M.", null,AlertType.INFO);
Display.getDisplay(this).setCurrent(alert);
}
}

public void itemStateChanged(Item i){
if(i == txt){
if(formulario.size() == 2)
formulario.delete(1);

if(txt.getString().length() == 8 || (txt.getString().length() == 12) && txt.getString().substring(0, 4).equals("+569")){
System.out.println(txt.getString());
String num = (txt.getString().length() == 12 )?txt.getString().substring(4):txt.getString();

char c = buscarCom(num.substring(0, 4));

if(c == 'T'){
imagenItem.setImage(imgMovistar);
formulario.append(imagenItem);
}
if(c == 'E'){
imagenItem.setImage(imgEntel);
formulario.append(imagenItem);
}
if(c == 'C'){
imagenItem.setImage(imgClaro);
formulario.append(imagenItem);
}
}
}
}

public char buscarCom(String num){
try {
InputStream in = getClass().getResourceAsStream("/datos.txt");

StringBuffer sb = new StringBuffer();

int ch;
while ((ch = in.read()) != -1){
if((char)ch == '\n'){
if(num.equals(sb.toString().substring(0, 4))){
in.close();
return sb.charAt(4);
}
sb = new StringBuffer();
}else{
sb.append((char)ch);
}
}

in.close();

} catch (Exception e) {
Alert alert = new Alert("Error!", "No se pudo acceder al archivo de datos", null,AlertType.ERROR);
alert.setTimeout(Alert.FOREVER);
Display.getDisplay(this).setCurrent(alert);
}
return 'x';
}
}

miércoles, 7 de mayo de 2008

Mostrar el contenido de un directorio servido por Tomcat

Para mostrar u ocultar el contenido de un directorio servido por Tomcat, se debe modificar la definición del servlet "default" en el archivo $(instalaciónDeTomcat)/conf/web.xml.

Cambiando

        <init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>


por: (para que muestre el directorio)

        <init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>

martes, 6 de mayo de 2008

Tutorial de Hibernate

Este tutorial se basa en el mapeo de una base de datos en Postgresql, utilizando eclipse y el Hibernate Tools.

Primero crearemos el usuario y la base de datos a utilizar
$ createuser -P -U postgres mundo
Enter password for new role:
Enter it again:
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) n
CREATE ROLE
$ createdb -U mundo -W mundo
Password:
CREATE DATABASE
$


Ahora con el siguiente script, creamos la estructura de la base de datos

mundo.sql
SET client_encoding = 'UTF8';
SET check_function_bodies = false;
SET client_min_messages = warning;

-- Table: continente

CREATE TABLE continente
(
codcontinente serial NOT NULL,
nombre character varying(50) NOT NULL,
CONSTRAINT pk_continente PRIMARY KEY (codcontinente)
)
WITH (OIDS=FALSE);
ALTER TABLE continente OWNER TO mundo;

-- Table: pais

CREATE TABLE pais
(
codpais serial NOT NULL,
valor character varying(50) NOT NULL,
codcontinente integer NOT NULL,
CONSTRAINT pk_pais PRIMARY KEY (codpais),
CONSTRAINT fk_continente FOREIGN KEY (codcontinente)
REFERENCES continente (codcontinente) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (OIDS=FALSE);
ALTER TABLE pais OWNER TO mundo;

-- Index: fki_pais_continente

CREATE INDEX fki_pais_continente
ON pais
USING btree
(codcontinente);


$ psql -U mundo -W -f mundo.sql
Password for user mundo:
SET
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE INDEX
$


Ahora crearemos la aplicación que utilizará estas dos tablas.

Primero creamos un "Java Proyect"


Le agregamos las librerías necesarias para Hibernate y el driver jdbc para Postgresql

Una vez creado el proyecto, agregamos el archivo de configuración de Hibernate


Lo dejamos en la raíz del directorio de recursos.


Definimos los parámetros de conexión con la base de datos.

Creamos el "Hibernate Console Configuration", este es el perfil que define todas las características del proyecto con Hibernate.


Una vez creado el "Console Configuration", podemos ir a la vista de Hibernate y ejecutar el generador de código.


Creamos un nuevo perfil.


Le indicamos las caracteristicas de nuestro proyecto.


Le idicamos que genere los archivos de configuración de Hibernate y las clases POJO. Y ejecutamos.


Aquí podemos ver el código generado.


Luego agregamos hibernate.revenge.xml, el archivo de filtro para la ingeniería inversa.

Le indicamos que se guarde en el directorio de recursos del proyecto.

Podemos agregar algún retoque, por ejemplo, que los campos INTEGER de la base de datos, sean mapeados como java.lang.Integer.


Retocamos las claves primarias, para que utilicen la secuencia definida en la base de datos.


Lo mismo con la otra tabla.


Ahora agregagemos un par de clases de servicio, que nos ayudaran con las operaciónes CRUD.

SessionFactory.java : como su nombre lo indica es una fábrica de sesiones.

package test;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
*/
public class SessionFactory {

/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal threadLocal = new ThreadLocal();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;

private SessionFactory() {
}

/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the SessionFactory if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();

if (session == null || !session.isOpen()) {
System.out.println("<<<<<<<<<>>>>>>>");
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}

return session;
}

/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}

/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);

if (session != null) {
session.close();
}
}

/**
* return session factory
*
*/
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}

/**
* return session factory
*
* session factory will be rebuilded in the next call
*/
public static void setConfigFile(String configFile) {
SessionFactory.configFile = configFile;
sessionFactory = null;
}

/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}

}



ControlHibernate.java
package test;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class ControlHibernate {

private static Logger log = Logger.getLogger(ControlHibernate.class);

public static List getObjetos(String hql) throws HibernateException {
List items = new ArrayList();
Session session = null;
Transaction tx = null;
session = SessionFactory.getSession();
try {
tx = session.beginTransaction();
items = session.createQuery(hql).list();
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
session.close();
}
return items;
}

public static void guardarObjeto(Object objeto, Integer codigo)
throws HibernateException {
Session session = null;
Transaction tx = null;
session = SessionFactory.getSession();
try {
tx = session.beginTransaction();
// modifica objeto
if ((codigo != null) && (codigo.intValue() != 0)) {
log.info("va a hacer 'merge' de objeto");
session.saveOrUpdate(objeto);
session.flush();
} else { // inserta objeto
log.info("va a hacer 'save' de objeto");
session.save(objeto);
}
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
session.close();
}
}
}

Como prueba final de este tutorial, Creamos una clase Prueba.java , que crea un objeto Pais, con un objeto Continente anidado y los almacena en la base de datos.


Aquí podemos observer que los datos se ingresaron correctamente.

También podemos utilizar el editor de sentencias HQL, para realizar pruebas.


Si tienes una crítica o aporte, no dudes en comentarla.

:wq

viernes, 2 de mayo de 2008

Creando un proyecto Flex con Java y BlazeDS con RemoteObject en entornos separados

En este tutorial explico paso a paso la creación de un proyecto Flex con Java en entornos separados (front-end - back-end), con BlazeDS y RemoteObject (en Linux).

Se asume tener instalado Jdk y con sus variables de entorno, sino puedes revisar aquí

Configuración del Back-end

Primero debemos bajar BlazeDS, en mi caso bajé el Turnkey, pues ya viene deployado el BlazeDS.
Lo dejé en /home/rene/blazeds_turnkey_3-0-0-544.

Ahora en eclipse creamos un Java Project


Le ponemos un nombre y le indicamos la ruta del Turnkey, como se vé en la imagen. Y siguiente


Establemos la carpeta src como "source folder", ya que por default no lo es. Le idicamos que las clases compiladas deben quedar en el directorio "classes". Y finalizamos

Creamos una clase de prueba.


Le ponemos nombre a la clase y la dejamos bajo un paquete.


Creamos un simple método que retorne un String.


Lo declaramos como "destination" en el archivo "flex/remoting-config.xml"


Agregamos una sección de "login-config" en el web.xml

<login-config>
<auth-method>BASIC</auth-method>
</login-config>



Guardamos todo y levantamos el servidor:

$ cd blazeds_turnkey_3-0-0-544/sampledb/
rene ~/blazeds_turnkey_3-0-0-544/sampledb $ ./startdb.sh
[Server@18a7efd]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@18a7efd]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@18a7efd]: Startup sequence initiated from main() method
[Server@18a7efd]: Loaded properties from [/home/rene/blazeds_turnkey_3-0-0-544/sampledb/server.properties]
[Server@18a7efd]: Initiating startup sequence...
[Server@18a7efd]: Server socket opened successfully in 29 ms.
[Server@18a7efd]: Database [index=0, id=0, db=file:flexdemodb/flexdemodb, alias=flexdemodb] opened sucessfully in 1203 ms.
[Server@18a7efd]: Startup sequence completed in 1233 ms.
[Server@18a7efd]: 2008-04-30 23:14:53.387 HSQLDB server 1.8.0 is online
[Server@18a7efd]: To close normally, connect and execute SHUTDOWN SQL
[Server@18a7efd]: From command line, use [Ctrl]+[C] to abort abruptly

$ cd blazeds_turnkey_3-0-0-544/tomcat/bin/
rene ~/blazeds_turnkey_3-0-0-544/tomcat/bin $ ./startup.sh
Using CATALINA_BASE: /home/rene/blazeds_turnkey_3-0-0-544/tomcat
Using CATALINA_HOME: /home/rene/blazeds_turnkey_3-0-0-544/tomcat
Using CATALINA_TMPDIR: /home/rene/blazeds_turnkey_3-0-0-544/tomcat/temp
Using JRE_HOME: /usr/local/jdk1.6.0_06
$
Comprobamos abriendo el navegador en http://localhost:8400

Configuración del Front-end

Ahora creamos un Flex Project (en el Flex Builder plugin para Linux)


En la configuración del server le indicamos donde están los servicio que vamos a consumir y donde queremos colocar lo archivos generado y compilados.

Creamos una simple aplicación que consuma el RemoteObject definido en el destination. Y ejecutamos la aplicación.


Al pinchar el botón, su label se cargará con lo que retorna el método de la clase java.

:wq

jueves, 24 de abril de 2008

Internacionalizacion en Flex 3

En este tutorial se explica como integrar la internacionalización en Flex 3.

Se asume tener instalado, configurado el Flex Builder, y un proyecto flex vacío.

  • Creamos una carpeta "locale" en la raiz del proyecto
  • Dentro de esta carpeta crearemos una carpeta por cada idioma, y con el nombre correspondiante ej: es_CL,en_US,pr_BR,ja_JP .. etc
  • Ahora, dentro de cada directorio de idioma crearemos un archivo de igual nombre, como puede ser "recursoForm.properties", lo importante es que debe terminar con ".properties".
  • En estos archivos colocaremoas las traducciones. ej:
locate/es_CL/recursoForm.properties
pais = Chile
flag = Embed("images/chile.gif")

locate/en_US/recursoForm.properties
pais = US
flag = Embed("images/us.gif")

locate/pt_BR/recursoForm.properties
pais = Brasil
flag = Embed("images/brasil.gif")

locate/ja_JP/recursoForm.properties
pais = Japon
flag = Embed("images/japon.gif")


  • Creamos las respectivas carpetas "images" en cada carpeta de los locales, donde colocamos las imagenes que hemos declarado.
  • Ahora desde la linea de comando "cmd" nos dirigimos directorio de instalacion del sdk que utilicemos, en mi caso es:

C:\Archivos de programa\Adobe\Flex Builder 3 Plug-in\sdks\3.0.0\bin>

  • Y ejecutamos el comando copylocale.exe, para cargar los nuevos idiomas, su sintaxis es: copylocale locale_original locale_nuevo

copylocale.exe en_US es_CL
copylocale.exe en_US pr_BR

  • El en_US y el ja_JP vienen cargador por defecto.
  • Podemos ver los que han sido cargado en :
C:\Archivos de programa\Adobe\Flex Builder 3 Plug-in\sdks\3.0.0\frameworks\locale

  • Ahora en las propiedades del proyecto, en la seccion "Flex Compiler", en los argumentos para el compilador, agregamos los nuevos locales:

-locale=es_ES,en_US -allow-source-path-overlap=true -source-path=..\locale\{locale}

  • Bién ahora solo que hacer una pequeña aplicación donde lo podamos ver.

Y ejecutando la aplicación se puede apreciar así:

Al seleccionar el pais, también se carga el Label y la Image correspondiente

Hay dos formas de buscar un recurso:

  • Una es usando la directiva @Resource: este es el método simple pero tiene varias limitaciones. Ejemplo, solo se puede usar en MXML, no se pueden cambiar los locales en tiempo de ejecución y solo devuelve Strings.

<mx:formitem label="@Resource(key='nombre', bundle='recursos')">
<mx:textinput>
</mx:textinput></mx:formitem>


  • La otra forma es usando los métodos de la clase ResourceManager (como se muestra en el ejemplo): puede retornar distintos tipos de datos como int, Boolean, Number. Se pueden cambiar los locales en tiempo de ejecución

Cambiando los mensajes del sistema

Para cambiar los mensajes del sistema como "yes" por "si" , vamos a la carpeta de los locales, en mi caso:
C:\Archivos de programa\Adobe\Flex Builder 3 Plug-in\sdks\3.0.0\frameworks\locale\es_CL

Abrimos el archivo "framework_rb.swc", puede ser con winzip. Y editamos el archivo "controls.properties".

Y cambiamos donde dice:

yesLabel=Yes

por

yesLabel=Si

Y así podemos seguir con todas la que queramos.

Guardamos los cambios. Volvemos a compilar el proyecto y apareceran los cambios

miércoles, 23 de abril de 2008

Creando un proyecto Flex con Java y BlazeDS con RemoteObject en un solo proyecto

En este tutorial se explica paso a paso la puesta en marcha de un proyecto Flex y Java con RemoteObject de BlazeDS, todo sobre Tomcat.

Se debe tener instalado eclipse wtp y Flex Builder como plugin

Agregamos el Tomcat Server al entorno de Eclipse.


Creamos un proyecto Flex

Seleccionamos la arquitectura J2EE y se define la carpeta de recursos java


Seleccionamos el Tomcat server que habíamos configurado previamente e idicamos la ubicación de BlazeDS


Una vez creado el proyecto crearemos una simple clase Java, con un método que retorne un String



Luego lo declaramos el destination en el archivo flex\remoting-config.xml


Debemos realizar este pequeño cambio. En el campo de Contex root de la ventana de propiedades del proyecto cambiamos /WebContent por /tmp , que es el nombre del proyecto


Escribimos el archivo mxml que consumirá el RemoteObject. En este caso, al pinchar el botón, se cargará en el label del botón, el retorno del método.

Y lo hechamos a correr en el servidor tomcat.





Finalmente, con bombos, platillos y "hola mundo" incluido, lo podemos ver en el navegador .

pd: el builder para Linux aún está muy verde para este tipo de proyecto(front-end y back-end todo en un proyecto) .. habrá que esperar un poco más. ¬¬

:wq

miércoles, 16 de abril de 2008

Creando una aplicación CRUD en Flex y PHP

Para crear una alicaciónCRUD en Flex con PHP a través de HTTPServices, debemos disponer de un servidor de http, php y mysql; como XAMPP. Aquí lo podemos ver corriendo.



Con el Flex builder instalado, procederemos a crear una aplicación Web Flex con PHP.

En la siguiente pantalla se deben ingresar los datos del servidor web. Y finalizar el asistente
.

Una vez creado el proyecto, usaremos el asistente para crear la aplicación CRUD desde una Base de datos.
Procederemos a crear el perfil de conección a la base de datos en "New" si no existe. Seleccionamos el proyecto, la tabla y su identificador. Y Finalizamos el asistente.


El proyecto ahora contiene todo el código necesario. De aquí podemos sacar muchas ideas. Ahora podemos ejecutamos la aplicación para probarla.



Y ya tenemos una aplicación que permite listar, crear , edición en linea y eliminación de registros de una base de datos.


Como se pudieron dar cuenta este tutorial lo he desarrollado en windows, ya que el Flex builder para Linux está recién en alpha 3, y no posee este wizard.

:wq