1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49:
50:
55: public final class FunctionCall
56: extends Expr
57: {
58:
59: final XPathFunctionResolver resolver;
60: final String name;
61: final List args;
62:
63: public FunctionCall(XPathFunctionResolver resolver, String name)
64: {
65: this(resolver, name, Collections.EMPTY_LIST);
66: }
67:
68: public FunctionCall(XPathFunctionResolver resolver, String name, List args)
69: {
70: this.resolver = resolver;
71: this.name = name;
72: this.args = args;
73: }
74:
75: public Object evaluate(Node context, int pos, int len)
76: {
77: if (resolver != null)
78: {
79: QName qname = QName.valueOf(name);
80: int arity = args.size();
81: XPathFunction function = resolver.resolveFunction(qname, arity);
82: if (function != null)
83: {
84:
85: if (function instanceof Expr)
86: {
87: if (function instanceof Function)
88: {
89: ((Function) function).setArguments(args);
90: }
91: return ((Expr) function).evaluate(context, pos, len);
92: }
93: else
94: {
95: List values = new ArrayList(arity);
96: for (int i = 0; i < arity; i++)
97: {
98: Expr arg = (Expr) args.get(i);
99: values.add(arg.evaluate(context, pos, len));
100: }
101: try
102: {
103: return function.evaluate(values);
104: }
105: catch (XPathFunctionException e)
106: {
107: e.printStackTrace(System.err);
108: throw new RuntimeException(e.getMessage(), e);
109: }
110: }
111: }
112: }
113: throw new IllegalArgumentException("Invalid function call: " +
114: toString());
115: }
116:
117: public Expr clone(Object context)
118: {
119: int len = args.size();
120: List args2 = new ArrayList(len);
121: for (int i = 0; i < len; i++)
122: {
123: args2.add(((Expr) args.get(i)).clone(context));
124: }
125: XPathFunctionResolver r = resolver;
126: if (context instanceof XPathFunctionResolver)
127: {
128: r = (XPathFunctionResolver) context;
129: }
130: return new FunctionCall(r, name, args2);
131: }
132:
133: public boolean references(QName var)
134: {
135: for (Iterator i = args.iterator(); i.hasNext(); )
136: {
137: if (((Expr) i.next()).references(var))
138: {
139: return true;
140: }
141: }
142: return false;
143: }
144:
145: public String toString()
146: {
147: StringBuffer buf = new StringBuffer();
148: buf.append(name);
149: buf.append('(');
150: int len = args.size();
151: for (int i = 0; i < len; i++)
152: {
153: if (i > 0)
154: {
155: buf.append(',');
156: }
157: buf.append(args.get(i));
158: }
159: buf.append(')');
160: return buf.toString();
161: }
162:
163: }