Revision 47378 trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/InstanceUtils.java

View differences:

InstanceUtils.java
17 17
        if( instance==null ) {
18 18
            throw new NullPointerException("An object pointer was expected to invoke method "+methodName+" and a null was received");
19 19
        }
20
        Class[] parameterTypes = new Class[args.length];
21
        Object[] parameters = new Object[args.length];
20
        Class<?> theClass = instance.getClass();
21
        Method method = getMethod(theClass, methodName, createParameterTypesAccurate(args));
22
        if( method == null ) {
23
            method = getMethod(theClass, methodName, createParameterTypesFuzzy(theClass, methodName, args));
24
        }
25
        if( method == null ) {
26
            method = getMethod(theClass, methodName, createParameterTypesAllObjects(args));
27
        }
28
        if( method == null ) {
29
            method = getMethod(theClass, methodName, createParameterTypesFromMethodNameAndParametersCount(theClass, methodName, args));
30
        }
31
        Object value = method.invoke(instance, args);
32
        return value;
33
    }
34
    
35
    private static Method getMethod(Class theClass, String methodName, Class[] parameterTypes) {
36
        if( parameterTypes==null ) {
37
            return null;
38
        }
39
        try {
40
            return theClass.getMethod(methodName, parameterTypes);
41
        } catch(NoSuchMethodException ex) {
42
        }
43
        return null;
44
    }
45
    
46
    private static Class[] createParameterTypesAccurate(Object[] parameters) {
47
        Class[] parameterTypes = new Class[parameters.length];
22 48
        for (int i = 0; i < parameters.length; i++) {
23
            Object parameter = args[i];
49
            Object parameter = parameters[i];
24 50
            parameters[i] = parameter;
25 51
            if( parameter==null ) {
26 52
                parameterTypes[i] = null;
......
28 54
                parameterTypes[i] = parameter.getClass();
29 55
            }
30 56
        }
31
        Class<?> theClass = instance.getClass();
32
        Method method = null;
33
        try {
34
            method = theClass.getMethod(methodName, parameterTypes);
35
        } catch(NoSuchMethodException ex) {
57
        return parameterTypes;
58
    }
59
    
60
    private static Class[] createParameterTypesAllObjects(Object[] parameters) {
61
        Class[] parameterTypes = new Class[parameters.length];
62
        for (int i = 0; i < parameters.length; i++) {
63
            Object parameter = parameters[i];
64
            parameters[i] = parameter;
65
            if( parameter==null ) {
66
                parameterTypes[i] = null;
67
            } else {
68
                parameterTypes[i] = Object.class;
69
            }
36 70
        }
37
        if( method == null ) {
38
            // Uf esto arregla cosas de StringBuilder.append, pero no
39
            // crea que sea correcto.
40
            for (int i = 0; i < parameters.length; i++) {
41
                Object parameter = args[i];
42
                parameters[i] = parameter;
43
                if( parameter==null ) {
44
                    parameterTypes[i] = null;
45
                } else {
46
                    parameterTypes[i] = Object.class;
47
                }
71
        return parameterTypes;
72
    }
73
    
74
    private static Class[] createParameterTypesFromMethodNameAndParametersCount(Class theClass, String methodName, Object[] parameters) {
75
        for (Method m : theClass.getMethods()) {
76
            if( StringUtils.equals(m.getName(), methodName) && parameters.length == m.getParameterTypes().length) {
77
                return m.getParameterTypes();
48 78
            }
49 79
        }
50
        try {
51
            method = theClass.getMethod(methodName, parameterTypes);
52
        } catch(NoSuchMethodException ex) {
53
        }
54
        if( method == null ) {
55
            // Esto es para esquivar casos como tener un ArrayList de objects y 
56
            // hacer algo como  arr.add(10). Dice que no hay ningun metodo add
57
            // que reciba un Integer, por que realmente el add esta declarado como
58
            // que recibe un object.
59
            // Ver TestInterpreter metodo testListAppend.
60
            for (Method m : theClass.getMethods()) {
61
                if( StringUtils.equals(m.getName(), methodName) && parameterTypes.length == m.getParameterTypes().length) {
62
                    parameterTypes = m.getParameterTypes();
80
        return null;
81
    }
82
    
83
    private static Class[] createParameterTypesFuzzy(Class theClass, String methodName, Object[] parameters) {
84
        for (Method m : theClass.getMethods()) {
85
            if( StringUtils.equals(m.getName(), methodName) && parameters.length == m.getParameterTypes().length) {
86
                int n = 0;
87
                Class[] parameterTypes = new Class[parameters.length];
88
                for (Class<?> expectedType : m.getParameterTypes()) {
89
                    Class<? extends Object> paramType = parameters[n].getClass();
90
                    if( expectedType == paramType ) {
91
                        parameterTypes[n++] = expectedType;
92
                        continue;
93
                    }
94
                    if( expectedType == Object.class ) {
95
                        parameterTypes[n++] = Object.class;
96
                        continue;
97
                    }
98
                    
99
                    //
100
                    // Aqui probablemente habria que hacer algunas otras 
101
                    // comprobaciones, por ejemplo, si expected es double y
102
                    // recibimos un entero, long o float... ? deberiamos
103
                    // aceptar ? ? Habria que convertir el valor a double ?
104
                    //
105
                    parameterTypes = null;
63 106
                    break;
64 107
                }
108
                if( parameterTypes!=null ) {
109
                    return parameterTypes;
110
                }
65 111
            }
66
            method = theClass.getMethod(methodName, parameterTypes);
67 112
        }
68
        Object value = method.invoke(instance, parameters);
69
        return value;
113
        return null;
70 114
    }
71 115
    
116
    
117
    
72 118
}

Also available in: Unified diff