Más Reflexión

Reflection es un API de Java que es muy útil y que es utilizada por muchos frameworks de Java, como Spring, Struts o Trapestry, ya que permite acceder a métodos, atributos y ver el comportamiento de una clase durante la ejecución del programa.

Reflection puede servir para crear entornos de desarrollo visuales, herramientas que sirvan para realizar pruebas a algún componente, herramientas de depuramiento (aka debugging) o algún marco de trabajo que cree instancias e inyecte propiedades de objetos a partir de un archivo de configuración

Así que está vez muestro una clase que realizó un compañero de trabajo ya hace algunos años y que permite crear instancias y/o acceder a las propiedades (a tráves de los métodos accesores) de manera reflexiva. Esta es una herramienta muy útil ya que permite obtener propiedades de objetos de manera que podemos usarla para ordenar beans de manera mas general sin tener que definir un comparator para cada bean dependiendo de la propiedad que se desee comparar, convertir una lista de un beans en un mapa o crear listas de con alguna de las propiedades del bean.


/*
* GenericBean.java
*
* Created on 22 de junio de 2006, 09:32 PM
*

*/

/**
*
* @author JM
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class GenericBean {
private Object o;
private Class beanClass;

/** Creates a new instance of GenericBean */
public GenericBean(String className) {
try {
beanClass = Class.forName(className);
Constructor c = beanClass.getConstructor();
o = c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}

public GenericBean(Object instance) {
o = instance;
beanClass = o.getClass();
}

public Object get(String property) {
Object ret = null;
property = property.substring(0, 1).toUpperCase()
+ property.substring(1);
try {
String methodName = "get" + property;
Method method = beanClass.getMethod(methodName);
ret = method.invoke(o);
}
catch(Exception e) {
try {
String methodName = "is" + property;
Method method = beanClass.getMethod(methodName);
ret = method.invoke(o);
}
catch(Exception ex) {
e.printStackTrace();
}
}

return ret;
}

public void set(String property, Object value) {
property = property.substring(0, 1).toUpperCase()
+ property.substring(1);
try {
Method method = beanClass.getMethod("set" + property, value
.getClass());
method.invoke(o, value);
} catch (Exception e) {
e.printStackTrace();
}
}

public Object getObject() {
return o;
}

public Class getObjectClass() {
return o.getClass();
}
}

Mañana escribiré como poder usar esta clase, porque la verdad ahorita ya es un poco noche jeje y ya me estoy quedando dormido. Sólo como recordatorio adicional, es importante recordad que utilizar Reflection genera bajas en el performance la máquina virtual ya que muchas veces no es posible utilizar los optimizadores con los que cuenta la JVM, como pueden ser en multiples llamadas a métodos, recursiones de cola etc...

Saludos
Gus

Anotaciones en Java

Nivel: Intermedio

Las anotaciones en Java, son marcas que se hacen a una parte del programa, que no tienen un efecto directo sobre el mismo pero que son reflexivas en la ejecución, es decir, pueden ser utilizadas por algún contenedor al momento de la ejecución del programa.


Las anotaciones son un tipo especial de modificador y puede ser usando junto a otros modificadores, tales como public, static, private etc... Digamos que las anotaciones son una forma de implementar una interfaz, sin que la clase lo haga directamente. Por ejemplo, creas un clase Perro, y entonces la anotas para decir que es un Animal, de está manera, en la ejecución del programa y utilizando reflexión es posible saber que cualquier objeto de clase Perro es un animal. Es decir estamos indicando que Perro es un animal y cumple una función similar a una interfaz.


@Animal
public class Perro {
//Algún buen metodo de la clase perro
}




Definir una anotación es algo muy sencillo, se hace de igual forma que una interfaz y se antepone una "@" al inicio de la palabra interface, y los métodos que contenga serán los elementos de la anotación, y sólo pueden regresar tipos primitivos, String y Enums.





public @interface Animal {
boolean vertebrado();
}


Con la anotación presentada anteriormente, podremos anotar alguna clase y definir si el Animal que estamos anotando es vertebrado o invertebrado


@Animal( vertebrado = true )
public class Perro {

}



De está forma en la ejecución del Programa podemos saber si que un objeto de clase Perro es un animal, y que tipo de animal es, además podemos especificar que la anotación solo sirve para anotar clases, ya que no podemos tener métodos de tipo animal. Y para hacer esto anotamos nuestra anotación. Entonces nuestra anotación queda así:


package anotaciones;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;



@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Animal {

boolean vertebrado();

}



De esa forma específicamos que la anotación sólo sirve para definir tipos. Ahora cómo usarlo en la ejecución:




package anotaciones;

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

public class Main {

@SuppressWarnings("unchecked")
public static void main(String[] args) {

//Creamos una Lista
List obj = new ArrayList();

//Agregamos 2 Perros
obj.add(new Perro());
obj.add(new Perro());

//Agregamos 1 String
obj.add("Soy un String");

System.out.println("Numero de animales en la lista:" + contarAnimales(obj));
}


public static int contarAnimales(List o ) {
if(o==null)
return 0;
else {
System.out.println("Empezando a contar");
int count = 0;
for (Object object : o) {
//System.out.println(object.getClass().getAnnotation(Animal.class));
if(object.getClass().isAnnotationPresent(Animal.class)) {
count++;
}
}
return count;
}
}

}



Aunque el ejemplo no es de lo más ortodoxo, da una muestra de lo que pueden hacer las anotaciones, y de como que es las utilizan los frameworks como JAXB o Spring 2.5 Anotado, en el cual se puede hacer el Autoalambrado, definir controlador, mapeos de request con anotaciones evitando tener que configurar un dispatcher servlet muy grande.

Saludos

Correr Archivos Jar en Vista

Si algún programa que instalamos como puede ser Winrar u otro compresor de datos se “adueño” de la asociación de los archivos jar podemos regresar esta asociación con la JVM para que al dar doble click en un archivo jar lo abra.

Para poder hacer esto solo es necesario bajar y correr el programa JarFix.

http://www.jonelo.de/java/jarfix/

Oracle compra Sun

El día 20 de Abril Oracle anunció que compraría Sun Microsystems por una suma de $7400 millones de dólares ( $7.4 billion dollars ) y cada acción se compro en 9.54 dólares. Por el momento sólo fue aceptado como un hecho unánime en Sun Microsystems, aunque aún falta que la transacción sea autorizada por el Gobierno.

Más información en:
http://www.bloomberg.com/apps/news?pid=20601087&sid=aVWptwRiZl1w&refer=home

XNA usando fuentes personalizadas

Cuando creamos un juego una de las partes importantes es el texto a desplegar, pero no siempre queremos usar las fuentes que tenemos instaladas en el sistema. Para poder usar otras fuentes debemos seguir los siguientes pasos.

  1. Bajar la Fuente
  2. Installarla en el Sistema 
    1. EN Windows XP: Copiar la fuente y pegarla en /Windows/Fonts
  3. Crear o Abrir el proyecto
  4. Click derecho en directorio Content
    1. Add new Item
    2. Crear un SpriteFont
      1. Cambiar en <FontName> el nombre de la fuente que bajamos
      2. Cambiar las caracteristicas de la fuente (Optional)
  5. Ahora ya podemos usar la fuente en el juego

Nota: Si le enviamos a alguna persona el proyecto de xna, tmb se tiene que instalar la fuente en la otra computadora, pero para la distribución del juego no es necesaria.

Blogger nube de Etiquetas

Si nosotros quisieramos agregar a nuestro blog una nube de etiquetas como la que tenemos en este blog podemos hacer uso de este tutorial.

http://phy3blog.googlepages.com/Beta-Blogger-Label-Cloud.html [En inglés]

Este tutorial es para Blogger y debemos de tener habilitado los “Labels” en las sección Widgets.

Crear funciones Nativas en Java...DLL

Bueno a veces es necesario crear funciones que sean dependientes del Sistema y que por lo tanto no pueden ser implementadas en Java, para eso existe JNI (Java Native Interface), que sirve para llamar a funciones nativas del Sistema y que pueden estar en un DLL (En Windows). Bien ahora veremos cómo crear una función nativa y que está sea llamada en Java. Lo primero que tenemos que hacer es crear una clase, y que tenga definido un método nativo, a su vez, la clase cargara una librería que se llamara "Project1" (así fue como le puso mi compilador de C jajaja) luego en el main, instanciaremos el objeto y llamaremos a la función:

public class HelloWorld {

public native void sayHello();

static {
System.loadLibrary("Project1");
}

public static void main(String[] args) {
new HelloWorld().sayHello();
}


}

El ejemplo es muy simple, sólo tenemos una clase con un método nativo, un bloque estático que carga una librería de nombre Project1, y un main, el cual crea la instancia y manda a llamar al método.Y ahora solo compilamos la clase:

javac HelloWorld.java

Ahora lo que tenemos que hacer es crear un header de C, que contenga la definición de la función que tenemos que implementar, Java tiene una herramienta para esto y entonces vamos a la línea de comandos de nuevo y tecleamos:

javah HelloWorld

Vamos a la carpeta donde estaba nuestra clase y ahi podemos ver que hay un archivo llamado HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_sayHello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


Este Header contiene la definición de la función que va a llamar la librería, ahora solo tenemos que crear una implementación que lucirá más o menos cómo esto:


#include
#include "HelloWorld.h"
#include

JNIEXPORT void JNICALL
Java_HelloWorld_sayHello(JNIEnv *env, jobject obj)
{
printf("Hello world Im a C Function\n");
return;
}


Y tenemos que compilar esto en un DLL, que es la parte un poco tediosa aunque si ya has usado alguna vez un compilador de C o C++ no tiene gran problema, puedes usar Borland, Blodshed Dev C++ ó el Visual C++. Yo lo compile con el Blodshed Dev C++ y aquí van las instrucciones:

1.- Una vez que tengas el archivo HelloWorld.h, abre el Bloodshed Dev C++ y crea un nuevo proyecto en la misma carpeta donde está el archivo, el proyecto especifica que sea de tipo DLL. (He aquí porque mi dll se llama Project1 jaja)

2.- Ve a Tools->Compiler Options, cuando abra el cuadro de diálogo, ve a la pestaña de Directories y luego a C++ Includes. (o a C includes dependiendo del tipo de proyecto que hayas creado) Ahi haz clic en el botoncito ese que es como una carpetita, y ve hasta donde este instalado tu Java y agrega la siguientes carpetas $JAVA_HOME\include y $JAVA_HOME\include\win32, donde $JAVA_HOME = Directorio donde está instalado tu Java, en mi caso: C:\Program Files\Java\jdk1.6.0_11, entonces mis rutas quedan así:
C:\Program Files\Java\jdk1.6.0_11\include
C:\Program Files\Java\jdk1.6.0_11\include\win32

3.- En el archivo .cpp que crea automáticamente el IDE copia el Siguiente código:

#include
#include "HelloWorld.h"
#include

JNIEXPORT void JNICALL
Java_HelloWorld_sayHello(JNIEnv *env, jobject obj)
{
printf("Hello world Im a C++\n");
return;
}

Y ve a Execute->Compile, y tu programa debe compilar y generar un archivo de nombre "Project1.dll" (o como le hayas puesto al proyecto.

Luego sólo ve a linea de comandos de nuevo y ejecuta:


java HelloWorld


Y el resultado debe ser:
Hello world Im a C Function

Y así has llamado a una función nativa :D Felicidades!

Espero te haya servido

Saludos!

Classpath en Java

Bueno, cuando estamos empezando a programar en Java, siempre existe la pregunta ¿Qué es el Classpath? Bueno, pues es muy simple, como lo dice su nombre es la ruta de clases que serán usadas para compilar y/o ejecutar un programa. Y su función es poder acceder a clases que están fuera del proyecto, cómo alguna librería externa, existen dos principales formas de configurar un Classpath, la 1era es configurar una variable de entorno del sistema de nombre CLASSPATH, y ahi ir colocando cada una de las carpetas o archivos *.jar que tenemos. La 2da es Compilar escribiendo directamente el Classpath como un parámetro al compilador de está forma:


javac -cp "RUTA" HolaMundo.java


Bueno ahora, para encontrar un uso, imaginemos que tenemos una libería de clases en la carpeta C:/lib, y ahí se encuentra la clase "Libreria"


public class Libreria {


public static void imprimir(String mensaje) {
System.out.println(mensaje);
}

}


Ahora imagina que la quieres usar en otro programa :

public class HolaMundo {

public static void main(String[] args) {

Libreria l = new Libreria();
l.imprimir("Hola Mundo");
}

}


Para poder compilar esto, tenemos que indicarle al compilador el CLASSPATH, que va a usar para compilar la clases y para eso hacemos esto:


javac -cp "C:\lib" HolaMundo.java


Y también para correr el programa se requiere especificar el classpath de la misma manera ya que de lo contrario obtendremos NoClassDefFoundError, porque no va a encontrar todas las clases necesarias. Entonces lo que hacemos es algo muy similar, excepto que está vez tenemos que indicar también la ruta en la que estamos y eso se hace con un "punto":


java -cp "C:\lib;." HolaMundo


Y con eso ya podemos corre nuestra clase.


Saludos!

Envío de paquetes entre VLANs

Para poder hacer envio de paquetes entre VLANs tenemos que hacer uso de algún dispositivo de capa 3, ya sea un Router o un Switch de capa 3.

La configuración para un Router Cisco es la siguiente:

Router#(config) interface f0/0.X                   //[ interface.númeroVlan ]

Router#(config-if) encapsulation dot1Q X    //[X = Número VLAN]

Router#(config-if) ip address address mask

Hay que configurar la interfaz f0/0 para cada de las VLANs

Usar cuentas de correo como Live ID

Si tenemos alguna cuenta que no sea "@msn, @hotmail, @live" aún podemos tener acceso a los servicios que ahora todo el suite de Live nos proporciona. Para poder realizar esto tenemos que entrar a:

http://www.passport.net

Le damos click al link donde podemos agregar una cuenta existente, nos pedirá nuestros datos, los agregamos y LISTO! podemos empezar a usar nuestra cuenta de correo (ej. Gmail) para servicios Live.

NOTA: En la parte de la contraseña no es necesaria que sea la misma contraseña que usamos para accesar a nuestro mail, y recordemos que por lo mismo cambios a la contraseña del mail no harán cambios a la contraseña del Live ID

Compilar todo un paquete java

Cuando compilamos un archivo java tenemos que usar la herramienta "javac"

javac Archivo.java

El problema lo tenemos cuando tenemos los archivos en paquetes y tenemos que compilar estos paquetes. Podriamos compiilar archivo por archivo pero tendriamos problema si estos archivos tienen referencias entre ellos por lo que habría compilar en un orden especifico los archivos. Para solucionar esto nos tenemos que poner en el directorio "root" del proyecto y aplicar la herramienta javac:

javac paquete/subpaquete/*.java

Esto nos compilará todo los archivos en ese paquete sin problemas, sin tener que estar compilando uno por uno.

Singleton: Mejorado

El Singleton, que presenté en mi entrada anterior es la implementación más común de un Singleton, sin embargo aun tiene algunos defectos, entre ellos está es que si esa clase la hacemos serializable, en cada ejecución se crearían diferentes instancias del singleton y tendríamos que crear un método para proteger esto. Y también tenemos el problema de que se puede accesar al constructor privado utilizando el API Reflection. Entonces aquí tenemos una forma más elegante de crear un Singleton:







public enum Singleton {

INSTANCE;

public void doSomething() {

}

}





Y luego cuando lo quisieramos usar, lo único que tendríamos que hacer sería esto:




public class Principal {

public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}

}




Y con eso tenemos una mejor y más sencilla implementación de un Singleton que nos garantiza que siempre será una única instancia.
SaludoSS!



Referencias:

Blooch, J. Effective Java 2nd Edition

Singleton en Java

Bien, un Singleton en términos muy generales es un objeto del cuál sólo podremos tener una instancia (es decir sólo podemos construir un objeto de esa clase durante la ejecución del programa). Programar un Singleton en Java es muy sencillo, lo único que tenemos que hacer es evitar que otras clases tengan acceso al constructor de mi clase singleton, y ¿cómo se hace eso? Pues sólo tenemos que hacer el constructor Privado, y luego hacemos un método que nos regrese la única Instancia creada.



public class Singleton {


//LA UNICA INSTANCIA QUE SERÁ CREADA
//LA CREAMOS DESDE QUE SE CARGUE LA CLASE
private static Singleton instancia = new Singleton();


//HACEMOS EL CONSTRUCTOR PRIVADO
//PARA QUE SÓLO PUEDA INSTANCIA OBJETOS DESDE LA MISMA CLASE
private Singleton() {
}


//MÉTODO PARA OBTENER LA INSTANCIA
public Singleton getInstance() {
return instancia;
}



}





En este ejemplo la instancia se crea, desde que se crea la clase, pero a veces es mejor crear la instancia hasta que se pide, entonces el código quedaría algo así:


public class Singleton {



//CREAMOS LA REFERENCIA
//AUNQUE AL INICIO APUNTA A NULL
private static Singleton instancia ;


//HACEMOS EL CONSTRUCTOR PRIVADO
//PARA QUE SÓLO PUEDA INSTANCIA OBJETOS DESDE LA MISMA CLASE
private Singleton() {
}


//MÉTODO PARA OBTENER LA INSTANCIA
public Singleton getInstance() {
if(instancia==null) //SI ES NULL
instancia = new Singleton(); //LO INSTANCIAMOS
return instancia;
}



}



Y con esto creamos nuestra clase Singleton, Luego ya le podemos programar métodos adicionales que son los servicios que va a ofrecer.

Saludos

Borrar Archivos con Java

Para poder borrar archivos del disco duro, primero tenemos que realizar una clase File

java.io.File file = java.oi.File("String con la ruta");
file.delete();



Este método nos regresa un boolean si es que lo pudo borrar.

En caso de que necesitemos crear archivos temporales y que se borren cuando terminemos el programa, podemos hacer uso de otro método de la clase file.


java.io.File file = java.oi.File("String con la ruta");
file.deleteOnExit();



Este metodo es void, pues como no es instantaneo no puede garantizar el borrado del archivo. Los archivos se borraran cuando el programa que los llamó se cierre.

Introducción a ANT

Nivel: Intermedio

ANT es una herramienta que se utiliza cuándo se está realizando un proyecto de programación y es necesario estar repitiendo tareas repetitivas cómo la compilación y la construcción. Ant está hecho en Java y es muy similar a Make, pero con las ventajas de ser multiplataforma y de no depender de las instrucciones del sistema operativo, sino que se configura con archivos XML. ANT es un proyecto open-source de la Apache Software Foundation.

Bien para comenzar a usar ANT, lo primero que hay que hacer es descargarlo de la página de apache, pueden escribir en google ANT y será alguno de los primeros resultados, sino aquí está la liga:

http://ant.apache.org/bindownload.cgi

Una vez que hayas descargado ANT, descomprime el arcihvo, ve al directorio /bin y agrega ese directorio al PATH de la Computadora, para que de esta forma, lo puedes llamar fácilmente y no tengas que escribir la ruta completa desde la línea de comandos. Probablemente tengas algunos problemas con el nombre de la carpeta, por los puntos y los guiónes medios, lo que yo hice fue cambiarle el nombre de la carpeta, y así el PATH me quedó asi: C:\ant\bin. También es necesario que tengas Java al menos 1.4. Finalmente para comprobar que lo hiciste bien escribe en una línea de comandos (MS-DOS).ant -version

Y si lo configuraste bien entonces verás información acerca de la versión de Ant que hayas descargado, sino está bien configurado te dirá que ant no es un comando reconocido.

Bien, ahora si vamos a la parte de usar ANT :D. Como ya mencione ANT es una herramienta que sirve para realizar procesos que es necesario repetir muchas veces cuándo estamos desarrollando un proyecto, cómo por ejemplo estar compilando y que tengamos una buena organización de directorios, y queremos separar nuestros archivos fuente de los ya compilados. Y que además se genere automáticamente un jar para correrlo.

Para usar ANT lo único que tenemos que hacer es crear un archivo XML de configuración el cual contendrá las instrucciones de que es lo queremos hacer. En ANT tenemos que configurar un target, que es la opción que va a ejecutar y luego las tareas que queremos que realice cuando seleccionemos ese objetivo. Bien para iniciar, vamos a establecer un nuevo proyecto, crearemos una carpeta que se llamara introduccionant, y ahí meteremos dos archivos:

HolaMundo.java (El Archivo que vamos a compilar y correr con ant)
build.xml (El Archivo de configuración de ANT)

HolaMundo.java
public class HolaMundo {

public static void main(String[] args) {

System.out.println("Hola Mundo");

}

}


build.xml


basedir="."
default="compilar">


debug="true"
deprecation="false"
optimize="false"
failonerror="true">






Primero definimos un proyecto, le damos un nombre, le ponemos el directorio base, en este caso es el mismo y por eso estamos poniendo el "." y el Target que por default va a ejecutar es el de nombre compilar. 

Después de eso tenemos que definir el target, el cuál tiene nombre compilar (es el default) Y en seguida se colocan las tareas que queremos realizar, en este caso solo queremos llamar a javac para que compile los archivos, nuestro directorio destino será el mismo y además colocamos unas opciones adicionales. Además cuando usamos javac, es obligatorio que tengamos definido donde están los archivos fuente por eso definimos también el directorio fuente que en este caso y por simplicidad también es el mismo.

Ahora lo único que tenemos que hacer es ir a una línea de comandos ir al directorio introduccionant y ejecutar el comando:

ant

Una vez esto el resultado dirá que el build se ha hecho satisfactoriamente y para los que han usado NetBeans, verán que la salida de consola es igual a la del IDE, esto es porque NetBeans utiliza Ant para hacer el build de nuestros proyectos. Y si vas al directorio utilizando un Explorador verás que tu archivo .class ya fue creado y puedes escribir en la línea de comandos: 

java HolaMundo

Linea de Comandos con Ant

Bien con eso hemos compilado nuestro primer programa utilizando ant, ahora lo único que tenemos que hacer es agregar más opciones a nuestro archivo build.xml para que podamos realizar más cosas utilizando ANT.

Saludos

Ordenar Listas en Java

Bien, ordenar una lista en Java, es algo muy sencillo, lo único que tenemos que hacer es llamar al método Sort, de la clase Collections, mandarle cómo parámetro la Lista que queremos ordenar y este los ordenara dado el orden natural del objeto (interfaz Comparable) , y si no queremos eso, pues podemos crear un Comparator. Sin embargo, imaginemos que tenemos aproximadamente unos 20 Objetos diferentes, que son JavaBeans, y que requerimos ordenarlos muchas veces por diferentes propiedades que tengan como por ejemplo Nombre, Apellido Paterno, Apellido Materno o Dirección. Tendríamos que estar creando Comparators para cada una de las propiedades que tenga el JavaBean y de está forma luego ya poder ordenarlos. Tendríamos al menos más de 20 Comparators diferentes que implementan casi la misma lógica, comparar un bean por alguna de sus propiedades, complicado no?. Bueno una solución para esto es el API de Reflection de Java





Bueno para inciar es necesario crear la firma de nuestro método, el cual podemos introducir en una clase Util que tenga métodos que usaremos durante nuestra aplicación, entonces la firma de nuesto método queda así:


import java.util.List;


public class Util {

public static void ordena(List lista, String propiedad) {

}

}

Lo único que hara el método sera recibir una lista, la cual ordenaremos, y la propiedad por la cual queremos ordenarla. Es decir vamos a ordenar una lista de Personas por Edad, entonces lo único que tendríamos que hacer es llamar a nuestro metodo ordena(lista,"nombre"), donde lista, es la Lista de Personas y nombre es una propiedad del JavaBean, es decir tiene métodos de setNombre() y getNombre().



Bien, ahora si pasemos a la parte divertida, para hacer esto, lo único que tenemos que hacer es mandar llamar al metodo Sort de la Clase Collections (la idea original) y crear un Comparator. Sólo que el Comparator, llamara a las propiedades de los objetos en tiempo de ejecución utilizando el API de Reflection de Java. Entonces hasta ahora lo que tenemos es esto:



import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class Util {

public static void ordena(List lista, String propiedad) {
Collections.sort(lista, new Comparator() {
public int compare(Object arg0, Object arg1) {
return 0;
}
});
}

}






Ahora lo que tenemos que hacer es llamar a los metodos getPropiedad de cada uno de los objetos y compararlos. Esto se logra llamando al método getClass() de la clase Object, luego con esa Clase, llamamaos al método getMethod() y se le manda como pararametro el nombre del método el cual sera getXXXXX donde XXXXX es nuestra propiedad, por ejemplo "nombre" llamara al método getNombre. Y finalmente se invocan esos métodos para obtener las propiedades y luego compararlas. El método invoke() de la clase Method, regresa siempre Object y si el método regresa tipos primitivos regresa su clase encapsuladora (int->Integer etc...).


import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class Util {

public static void ordena(List lista, final String propiedad) {
Collections.sort(lista, new Comparator() {

public int compare(Object obj1, Object obj2) {

Class clase = obj1.getClass();
String getter = "get" + Character.toUpperCase(propiedad.charAt(0)) + propiedad.substring(1);
try {
Method getPropiedad = clase.getMethod(getter);

Object propiedad1 = getPropiedad.invoke(obj1);
Object propiedad2 = getPropiedad.invoke(obj2);

//AUN TENEMOS QUE COMPARARLAS

}
catch(Exception e) {
e.printStackTrace();
}





return 0;
}
});
}


}



Por último solo falta comparar las propiedades, para esto utilizaremos el operador instanceof, para saber si la propiedad es comparable utilizando compareTo(), de lo contrario usaremos el metodo equals para comparar los objetos y si no son iguales regresaremos 1 (Que en realidad esto no es de mucha utilidad de cualquier forma jaja, pero es lo único que se puede hacer). Además al parámetro de la propiedad, tenemos que agregar la opcion final, porque será usado dentro de la clase Comparator que estamos definiendo internamente.



import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;



public class Util {

public static void ordena(List lista, final String propiedad) {
Collections.sort(lista, new Comparator() {

public int compare(Object obj1, Object obj2) {

Class clase = obj1.getClass();
String getter = "get" + Character.toUpperCase(propiedad.charAt(0)) + propiedad.substring(1);
try {
Method getPropiedad = clase.getMethod(getter);

Object propiedad1 = getPropiedad.invoke(obj1);
Object propiedad2 = getPropiedad.invoke(obj2);

if(propiedad1 instanceof Comparable && propiedad2 instanceof Comparable) {
Comparable prop1 = (Comparable)propiedad1;
Comparable prop2 = (Comparable)propiedad2;
return prop1.compareTo(prop2);
}//CASO DE QUE NO SEA COMPARABLE
else {
if(propiedad1.equals(propiedad2))
return 0;
else
return 1;

}

}
catch(Exception e) {
e.printStackTrace();
}
return 0;
}
});
}


}



Bien de esta forma tenemos terminado nuestro método, ahora solo falta probarlo, y para esto crearemos un Main, con una Lista de Objetos de Clase Persona, que son un JavaBean y la Ordenaremos. Además al método agregamos una anotación para que elimine las Warnings y el compilador no este dando lata jaja. Por último nuestra clase luce así:


import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;



public class Util {

@SuppressWarnings("unchecked")
public static void ordena(List lista, final String propiedad) {
Collections.sort(lista, new Comparator() {

public int compare(Object obj1, Object obj2) {

Class clase = obj1.getClass();
String getter = "get" + Character.toUpperCase(propiedad.charAt(0)) + propiedad.substring(1);
try {
Method getPropiedad = clase.getMethod(getter);

Object propiedad1 = getPropiedad.invoke(obj1);
Object propiedad2 = getPropiedad.invoke(obj2);

if(propiedad1 instanceof Comparable && propiedad2 instanceof Comparable) {
Comparable prop1 = (Comparable)propiedad1;
Comparable prop2 = (Comparable)propiedad2;
return prop1.compareTo(prop2);
}//CASO DE QUE NO SEA COMPARABLE
else {
if(propiedad1.equals(propiedad2))
return 0;
else
return 1;

}

}
catch(Exception e) {
e.printStackTrace();
}
return 0;
}
});
}

public static void main(String[] args) {
List<Persona> personas = new ArrayList<Persona>();


personas.add(new Persona("Gustavo",25));
personas.add(new Persona("Pedro",32));
personas.add(new Persona("Pablo",15));
personas.add(new Persona("Juan",10));
personas.add(new Persona("Ramiro",50));
personas.add(new Persona("Daniel",81));
personas.add(new Persona("Hector",23));

System.out.print("Lista sin ordenar:");
System.out.println(personas);
System.out.println();


//LLAMAMOS A ORDENA POR NOMBRE
ordena(personas,"nombre");
System.out.print("Ordenadas por Nombre:");
System.out.println(personas);
System.out.println();

//LLAMAMOS A ORDENA POR EDAD
ordena(personas,"edad");
System.out.print("Ordenadas por Edad:");
System.out.println(personas);
System.out.println();

}


}

class Persona {

String nombre;
int edad;



public Persona(String nombre, int edad) {
super();
this.nombre = nombre;
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}

//SOLO PARA QUE SEA MAS FACIL VER LOS DATOS
public String toString() {
return nombre + " " + edad;
}

}





Aún habría algunas cosas que agregar a nuestro método, cómo manejo correcto de excepciones, ponerlo en una clase más adecuada etc... Pero en Escencia ya está terminado y lo podremos usar y reusar en muchos de nuestros proyectos!



Espero te haya servido
Saludos


Apagar la computadora automáticamente (XP)

A veces nosotros necesitamos dejar la computadora prendida bajando algo o realizando alguna tarea, si nos tuvieramos que ir, nos gustaría poder apagarla automáticamente. Para realizar esto haremos uso de un commando que nos proporciona el sistema operativo.

Para usarlo tenemos que entrar a INICIO -> Ejecutar...

shutdown -s -f - t [tiempoEnSegundos]

Con este comando le decimos que apague la computadora y que si alguna aplicación no responde la finalice, además de asignar el tiempo en que queremos que se apague.

PHP: Un lenguaje Sencillo

En los últimos años, PHP se ha convertido en un lenguaje para programación web muy utilizado, existen muchas aplicaciones desarrolladas utilizándolo y muy grandes (como Facebook). Además, hoy en día es posible programar aplicaciones de escitorio utilizando PHP (sí, ya es posible) utilizando las librerías GTK para la interfaz gráfica. También existe un gran soporte en Internet, hay demasiados foros que contienen información del mismo, una gran cantidad de librerías con funciones ya hechas e incluso paquetes totalmente gratis, gestores de Contenido, Foros, Carritos de Compras, Galerías de Imágenes, Lectores de RSS, entre muchas otras. Cuenta con soporte multiplataforma, las funciones son llamadas nativas (no está implementado sobre ninguna máquina virtual como Java) y cuenta con gran conectividad con MySQL.

Sin embargo hablando como programador, más que como un usuario "que descarga paquetes", creo que PHP es HORRENDO, tiene como origen un modelo de programación en web antiguo, el soporte que tiene para la programación orientada a objetos es nefasto (incluso en PHP5 que dicen que SUPUESTAMENTE mejoró mucho), su naturaleza fomenta en la mayoría de programadores mezclar completamente el código de la lógica del negocio con la vista. El poder utilizar variables donde sea, hace que sea más difícil la corrección de bugs, ya que puede llegar a confundir las variables $id_usuario con $id_usario y tener errores de ejecución, y debido a que PHP "lo permite" es muy dificil de corregir.


PHP no se utiliza para la creación de aplicación empresariales, a veces resulta muy complicado implementar patrones de diseño ya que no tiene gran soporte de la programación orientada a objetos, no es Como Java, que es 100% Orientado a Objetos en el que incluso las funciones nativas o librerías que vienen incluidas en el JRE residen siempre en un objeto. Las empresas de desarrollo, nunca eligen a PHP para un proyecto grande, ya que su arquitectura no lo permite.

Otro problema, el principal y más grande que yo veo en PHP, es que muchos de los programadores que aprenden está tecnología, lo hacen porque necesitan hacer una página web que sea interactiva y que permita el registro de usuarios, no estudian Programación Orientada a Objetos, ni siquiera se preocupan de Patrón Modelo Vista Controlador, hacen un revoltijo en las páginas de código HTML, CSS, Javascript y PHP (Ya que así es como se vende PHP, "APRENDA PHP, Sólo con saber un poco de HTML y CSS). A diferencia de aquellos que aprenden a programar en Java o .NET (no todos) adquieren mejores prácticas de Programación, tienen una mejor idea de cómo hacer un Modelado de un Sistema (aclaro, no todos jeje) y son más disciplinados para programar (REPITO: NO TODOS JAJA).

Se habla mucho acerca de Java VS PHP o .NET VS PHP, sin embargo creo que ni siquiera hay puntos de comparación, .NET y Java, son tecnologías en las que se pueden realizar un sin fin de cosas, aplicaciones web, aplicaciones Standalone, Celulares, Servicios Web, RMI, RPC, DAEMONS, Interpretes, Compiladores. Tienen gran Soporte de Transacciones, y no creo que haya un Framework para aplicaciones web tan completo y tan robusto como Spring. PHP es un lenguaje que sirve para aplicaciones sencillas, carritos de compras y foros, pero no creo que al menos en el corto plazo se pueda comparar con un lenguaje y una Suite tan completa y poderosa como Java. Claro la curva de aprendizaje de Java, es mucho más grande que la de PHP, pero los beneficios que trae también son así, además aprender a programar en un lenguaje de programación como Java hace que los programadores comprendan en funcionamiento de un simple programa y así que puedan ir aprendiendo hasta llegar a comprender un Sistema Distribuido, que utiliza Web Services y bases de datos distribuidas que soporta transacciones, a diferencia de muchos que aprenden PHP, que a veces ni siquiera llegan a comprender el esquema Cliente-Servidor.