package com.occamlab.te.saxon; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import net.sf.saxon.Controller; import net.sf.saxon.expr.Expression; import net.sf.saxon.expr.ExpressionTool; import net.sf.saxon.expr.StaticContext; import net.sf.saxon.expr.XPathContext; import net.sf.saxon.om.EmptyIterator; import net.sf.saxon.om.SequenceIterator; import net.sf.saxon.om.StructuredQName; import net.sf.saxon.om.ValueRepresentation; import net.sf.saxon.trans.XPathException; import net.sf.saxon.value.ObjectValue; import net.sf.saxon.value.SequenceType; import net.sf.saxon.value.Value; import com.occamlab.te.TEClassLoader; import com.occamlab.te.TECore; import com.occamlab.te.Test; import com.occamlab.te.index.FunctionEntry; import com.occamlab.te.util.Misc; public class TEJavaFunctionCall extends TEFunctionCall { FunctionEntry fe; Method[] methods = null; public TEJavaFunctionCall(FunctionEntry fe, StructuredQName functionName, Expression[] staticArgs, StaticContext env) throws XPathException { super(functionName, staticArgs, env); this.fe = fe; } public SequenceIterator iterate(XPathContext context) throws XPathException { Controller controller = context.getController(); ObjectValue ov = (ObjectValue) controller.getParameter("{" + Test.TE_NS + "}core"); TECore core = (TECore) ov.getObject(); TEClassLoader cl = core.getEngine().getClassLoader( core.getOpts().getSourcesName()); if (methods == null) { methods = new Method[fe.getMaxArgs() + 1]; for (int i = fe.getMinArgs(); i <= fe.getMaxArgs(); i++) { try { methods[i] = Misc.getMethod(fe.getClassName(), fe.getMethod(), cl, i); } catch (Exception e) { throw new XPathException("Error: Unable to bind function " + fe.getName(), e); } } } Object instance = null; if (fe.isInitialized()) { instance = core.getFunctionInstance(fe.hashCode()); if (instance == null) { try { instance = Misc.makeInstance(fe.getClassName(), fe.getClassParams(), cl); core.putFunctionInstance(fe.hashCode(), instance); } catch (Exception e) { throw new XPathException(e); } // List<Node> classParams = fe.getClassParams(); // Object[] classParamObjects = new Object[classParams.size()]; // Constructor[] constructors = // method.getDeclaringClass().getConstructors(); // for (int i = 0; i < constructors.length; i++) { // Class<?>[] types = constructors[i].getParameterTypes(); // if (types.length == classParams.size()) { // boolean constructorCorrect = true; // for (int j = 0; j < types.length; j++) { // Node n = classParams.get(j); // if (types[j].isAssignableFrom(Node.class)) { // classParamObjects[j] = n; // } else if (types[j] == String.class) { // classParamObjects[j] = n.getTextContent(); // } else if (types[j] == Character.class) { // classParamObjects[j] = n.getTextContent().charAt(0); // } else if (types[j] == Boolean.class) { // classParamObjects[j] = // Boolean.parseBoolean(n.getTextContent()); // } else if (types[j] == Byte.class) { // classParamObjects[j] = Byte.parseByte(n.getTextContent()); // } else if (types[j] == Short.class) { // classParamObjects[j] = Short.parseShort(n.getTextContent()); // } else if (types[j] == Integer.class) { // classParamObjects[j] = Integer.parseInt(n.getTextContent()); // } else if (types[j] == Float.class) { // classParamObjects[j] = Float.parseFloat(n.getTextContent()); // } else if (types[j] == Double.class) { // classParamObjects[j] = // Double.parseDouble(n.getTextContent()); // } else { // constructorCorrect = false; // break; // } // } // if (constructorCorrect) { // try { // instance = constructors[i].newInstance(classParamObjects); // core.putFunctionInstance(fe.getId(), instance); // } catch (Exception e) { // throw new XPathException(e); // } // break; // } // } // } } } Expression[] argExpressions = getArguments(); Object[] javaArgs = new Object[argExpressions.length]; Method m; Class[] types; int argsIndex; if (fe.usesContext()) { m = methods[argExpressions.length + 1]; types = m.getParameterTypes(); ValueRepresentation vr = context.getContextItem(); javaArgs[0] = Value.asValue(vr).convertToJava(types[0], context); argsIndex = 1; } else { m = methods[argExpressions.length]; types = m.getParameterTypes(); argsIndex = 0; } for (int i = 0; i < argExpressions.length; i++) { ValueRepresentation vr = ExpressionTool.lazyEvaluate( argExpressions[i], context, 1); // Value v = Value.asValue(vr); // boolean b = (v instanceof AtomicValue); // SequenceIterator it = Atomizer.getAtomizingIterator(v.iterate()); // if (it instanceof AxisIterator) { // AxisAtomizingIterator aai = new // AxisAtomizingIterator((AxisIterator)it); // } // Object o = it.next(); // javaArgs[argsIndex] = v.convertToJava(String.class, context); javaArgs[argsIndex] = Value.asValue(vr).convertToJava( types[argsIndex], context); argsIndex++; } Object result; try { result = m.invoke(instance, javaArgs); } catch (Exception e) { Throwable cause = e; if (e instanceof InvocationTargetException) { cause = e.getCause(); } String msg = "Error invoking " + fe.getId() + "\n" + cause.getClass().getName(); if (cause.getMessage() != null) { msg += ": " + cause.getMessage(); } throw new XPathException(msg, cause); } if (result == null) { return EmptyIterator.getInstance(); } else { Value v = Value.convertJavaObjectToXPath(result, SequenceType.ANY_SEQUENCE, context); return v.iterate(); } } }