jeudi 4 juin 2015

Reflection: How to compare two objects from unkown type

I'm doing an application that do custom decision making. Let's say I configure in a table Attributes:

id - Variable Name - Variable Type - Object Cannonical Name

1 - name - java.lang.String - com.megagroup.mgestion.jpa.entidades.procesos.Tramite

2 - tipo - java.lang.String - com.megagroup.mgestion.jpa.entidades.procesos.Tramite

What I'm trying to do is on runtime know the valor of that variable to take some decisions. In another table called Decisions I save something like this:

idAttribute1 - idAttribute2 - Operator - IfGoTo - ElseGoTo

1 - 2 - > - Activity1 - Activity2

And Now. I have these methods:

public Object runGetter(Field field, Class o, Object instance) {
    for (Method method : o.getMethods()) {
        if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3))) {
            if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase())) {
                try {
                    System.out.println("Method Name: " + method.getName());
                    return method.invoke(instance);
                } catch (IllegalAccessException | InvocationTargetException e) {
                }
            }
        }
    }
    return null;
}

After I search for the field in the class, I will run its getter and catch an Object in return. That's the Object I want to compare. But I don't know what is that object so I did something like this for find it's type (which I save in the table):

public <T> T convertirObjeto(Object objetoAConvertir, Class<T> claseDestino) {
try {
    return claseDestino.cast(objetoAConvertir);
} catch(ClassCastException e) {
    return null;
}

That will return me something like String.class, Integer.class.

My idea was that I could do the first method, then call the second one sending the first method's return object and get in return an object. So let's said I save an Integer. I wish to compare if Integer 1 is higher or lower than Integer 2. My theory (wish possibly is very stupid) said that I can do:

 if (convertirObjeto(obtenerValorAtributo(atributo1),Class.forName(atributo1.getTipoAtributo())) <convertirObjeto(obtenerValorAtributo(atributo2),Class.forName(atributo2.getTipoAtributo()))) {

Instead of just cast

(Integer) obtenerValorAtributo(atributo2)

But when I try to compare that the compiler throws the following error:

Bad Operand types for binary operator '<'
First type: CAP#1
Second Type: CAP#2
Where CAP#1, CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends Object from capture of ?

I think, the compiler is trying to tell me: Sir, you don't know what these objects are, stop trying to burn me please. My question are:

If(Is there a *easier* solution for my problem than all that reflection I'm trying to do?)
Else If(Is there a way to fix that problem so I could compare two objects without knowing the type?)





Aucun commentaire:

Enregistrer un commentaire