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