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