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
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