1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jxpath.functions;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22
23 import org.apache.commons.jxpath.ExpressionContext;
24 import org.apache.commons.jxpath.Function;
25 import org.apache.commons.jxpath.JXPathInvalidAccessException;
26 import org.apache.commons.jxpath.util.TypeUtils;
27 import org.apache.commons.jxpath.util.ValueUtils;
28
29
30
31
32
33
34
35 public class MethodFunction implements Function {
36
37 private Method method;
38 private static final Object[] EMPTY_ARRAY = new Object[0];
39
40
41
42
43
44 public MethodFunction(Method method) {
45 this.method = ValueUtils.getAccessibleMethod(method);
46 }
47
48 public Object invoke(ExpressionContext context, Object[] parameters) {
49 try {
50 Object target;
51 Object[] args;
52 if (Modifier.isStatic(method.getModifiers())) {
53 target = null;
54 if (parameters == null) {
55 parameters = EMPTY_ARRAY;
56 }
57 int pi = 0;
58 Class[] types = method.getParameterTypes();
59 if (types.length >= 1
60 && ExpressionContext.class.isAssignableFrom(types[0])) {
61 pi = 1;
62 }
63 args = new Object[parameters.length + pi];
64 if (pi == 1) {
65 args[0] = context;
66 }
67 for (int i = 0; i < parameters.length; i++) {
68 args[i + pi] =
69 TypeUtils.convert(parameters[i], types[i + pi]);
70 }
71 }
72 else {
73 int pi = 0;
74 Class[] types = method.getParameterTypes();
75 if (types.length >= 1
76 && ExpressionContext.class.isAssignableFrom(types[0])) {
77 pi = 1;
78 }
79 target =
80 TypeUtils.convert(
81 parameters[0],
82 method.getDeclaringClass());
83 args = new Object[parameters.length - 1 + pi];
84 if (pi == 1) {
85 args[0] = context;
86 }
87 for (int i = 1; i < parameters.length; i++) {
88 args[pi + i - 1] =
89 TypeUtils.convert(parameters[i], types[i + pi - 1]);
90 }
91 }
92
93 return method.invoke(target, args);
94 }
95 catch (Throwable ex) {
96 if (ex instanceof InvocationTargetException) {
97 ex = ((InvocationTargetException) ex).getTargetException();
98 }
99 throw new JXPathInvalidAccessException("Cannot invoke " + method,
100 ex);
101 }
102 }
103
104 public String toString() {
105 return method.toString();
106 }
107 }