// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) fieldsfirst lnc
// Source File Name: FunctionProxy.java
package com.icl.saxon.expr;
import com.icl.saxon.Context;
import com.icl.saxon.Controller;
import com.icl.saxon.om.NodeEnumeration;
import com.icl.saxon.om.NodeInfo;
import java.lang.reflect.*;
import java.util.Vector;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
// Referenced classes of package com.icl.saxon.expr:
// Function, XPathException, Value, BooleanValue,
// NumericValue, StringValue, EmptyNodeSet, Expression,
// NodeSetExtent, ObjectValue, SingletonNodeSet
public class FunctionProxy extends Function
{
private Class theClass;
private Vector candidateMethods;
private XPathException theException;
private String name;
private Class resultClass;
public FunctionProxy()
{
/* 26*/ candidateMethods = new Vector();
/* 27*/ theException = null;
/* 29*/ resultClass = null;
}
public boolean setFunctionName(Class class1, String s)
{
/* 54*/ boolean flag = false;
/* 57*/ name = s;
/* 58*/ int i = getNumberOfArguments();
/* 59*/ int j = i;
/* 61*/ theClass = class1;
/* 65*/ if(name.equals("new"))
{
/* 67*/ int k = theClass.getModifiers();
/* 68*/ if(Modifier.isAbstract(k))
{
/* 69*/ theException = new XPathException("Class " + theClass + " is abstract");
/* 70*/ return false;
}
/* 72*/ if(Modifier.isInterface(k))
{
/* 73*/ theException = new XPathException(theClass + " is an interface");
/* 74*/ return false;
}
/* 76*/ if(Modifier.isPrivate(k))
{
/* 77*/ theException = new XPathException("Class " + theClass + " is private");
/* 78*/ return false;
}
/* 80*/ if(Modifier.isProtected(k))
{
/* 81*/ theException = new XPathException("Class " + theClass + " is protected");
/* 82*/ return false;
}
/* 85*/ resultClass = theClass;
/* 86*/ Constructor aconstructor[] = theClass.getConstructors();
/* 87*/ for(int l = 0; l < aconstructor.length; l++)
{
/* 88*/ flag = true;
/* 89*/ Constructor constructor = aconstructor[l];
/* 90*/ if(constructor.getParameterTypes().length == i)
{
/* 91*/ flag = true;
/* 92*/ candidateMethods.addElement(constructor);
}
}
/* 95*/ if(flag)
{
/* 96*/ return true;
} else
{
/* 98*/ theException = new XPathException("No constructor with " + i + (i != 1 ? " parameters" : " parameter") + " found in class " + theClass.getName());
/* 101*/ return false;
}
}
/* 107*/ StringBuffer stringbuffer = new StringBuffer();
/* 108*/ boolean flag1 = false;
/* 109*/ for(int i1 = 0; i1 < name.length(); i1++)
{
/* 110*/ char c = name.charAt(i1);
/* 111*/ if(c == '-')
{
/* 112*/ flag1 = true;
} else
{
/* 114*/ if(flag1)
/* 115*/ stringbuffer.append(Character.toUpperCase(c));
/* 117*/ else
/* 117*/ stringbuffer.append(c);
/* 119*/ flag1 = false;
}
}
/* 123*/ name = stringbuffer.toString();
/* 127*/ if(name.equals("if"))
/* 128*/ name = "IF";
/* 133*/ Method amethod[] = theClass.getMethods();
/* 134*/ boolean flag2 = true;
/* 135*/ for(int j1 = 0; j1 < amethod.length; j1++)
{
/* 137*/ Method method = amethod[j1];
/* 139*/ if(method.getName().equals(name) && Modifier.isPublic(method.getModifiers()))
{
/* 141*/ flag = true;
/* 142*/ if(flag2)
/* 143*/ if(resultClass == null)
/* 144*/ resultClass = method.getReturnType();
/* 146*/ else
/* 146*/ flag2 = method.getReturnType() == resultClass;
/* 150*/ Class aclass[] = method.getParameterTypes();
/* 151*/ boolean flag3 = Modifier.isStatic(method.getModifiers());
/* 156*/ j = flag3 ? i : i - 1;
/* 158*/ if(j >= 0)
{
/* 163*/ if(aclass.length == j && (j == 0 || aclass[0] != (com.icl.saxon.Context.class)))
{
/* 167*/ flag = true;
/* 168*/ candidateMethods.addElement(method);
}
/* 173*/ if(aclass.length == j + 1 && (aclass[0] == (com.icl.saxon.Context.class) || aclass[0] == (org.w3c.xsl.XSLTContext.class)))
{
/* 176*/ flag = true;
/* 177*/ candidateMethods.addElement(method);
}
}
}
}
/* 183*/ if(!flag2)
/* 184*/ resultClass = null;
/* 189*/ if(flag)
{
/* 190*/ return true;
} else
{
/* 192*/ theException = new XPathException("No method matching " + name + " with " + j + (j != 1 ? " parameters" : " parameter") + " found in class " + theClass.getName());
/* 196*/ return false;
}
}
public int getDataType()
{
/* 208*/ if(resultClass == null || resultClass == (com.icl.saxon.expr.Value.class))
/* 209*/ return -1;
/* 210*/ if(resultClass.toString().equals("void"))
/* 211*/ return 4;
/* 212*/ if(resultClass == (java.lang.String.class) || resultClass == (com.icl.saxon.expr.StringValue.class))
/* 213*/ return 3;
/* 214*/ if(resultClass == (java.lang.Boolean.class) || resultClass == Boolean.TYPE || resultClass == (com.icl.saxon.expr.BooleanValue.class))
/* 216*/ return 1;
/* 217*/ if(resultClass == (java.lang.Double.class) || resultClass == Double.TYPE || resultClass == (java.lang.Float.class) || resultClass == Float.TYPE || resultClass == (java.lang.Long.class) || resultClass == Long.TYPE || resultClass == (java.lang.Integer.class) || resultClass == Integer.TYPE || resultClass == (java.lang.Short.class) || resultClass == Short.TYPE || resultClass == (java.lang.Byte.class) || resultClass == Byte.TYPE || resultClass == (com.icl.saxon.expr.NumericValue.class))
/* 224*/ return 2;
/* 225*/ return !(com.icl.saxon.expr.NodeSetValue.class).isAssignableFrom(resultClass) && !(com.icl.saxon.om.NodeEnumeration.class).isAssignableFrom(resultClass) && !(org.w3c.dom.NodeList.class).isAssignableFrom(resultClass) && !(org.w3c.dom.Node.class).isAssignableFrom(resultClass) ? 6 : 4;
}
public String getName()
{
/* 240*/ return name;
}
public Expression simplify()
throws XPathException
{
/* 248*/ for(int i = 0; i < getNumberOfArguments(); i++)
/* 249*/ super.argument[i] = super.argument[i].simplify();
/* 255*/ if(candidateMethods.size() > 1)
{
/* 256*/ boolean flag = true;
/* 257*/ for(int j = 0; j < getNumberOfArguments(); j++)
{
/* 258*/ int k = super.argument[j].getDataType();
/* 259*/ if(k != -1 && k != 6)
/* 260*/ continue;
/* 260*/ flag = false;
/* 261*/ break;
}
/* 264*/ if(flag)
{
/* 266*/ Value avalue[] = new Value[getNumberOfArguments()];
/* 267*/ for(int l = 0; l < getNumberOfArguments(); l++)
/* 268*/ switch(super.argument[l].getDataType())
{
/* 270*/ case 1: // '\001'
/* 270*/ avalue[l] = new BooleanValue(true);
break;
/* 273*/ case 2: // '\002'
/* 273*/ avalue[l] = new NumericValue(1.0D);
break;
/* 276*/ case 3: // '\003'
/* 276*/ avalue[l] = new StringValue("");
break;
/* 279*/ case 4: // '\004'
/* 279*/ avalue[l] = new EmptyNodeSet();
break;
}
/* 284*/ try
{
/* 284*/ Object obj = getBestFit(avalue);
/* 285*/ candidateMethods = new Vector();
/* 286*/ candidateMethods.addElement(obj);
}
/* 288*/ catch(XPathException xpathexception)
{
/* 288*/ theException = xpathexception;
}
}
}
/* 292*/ return this;
}
public int getDependencies()
{
/* 302*/ int i = 0;
/* 304*/ i = 56;
/* 306*/ for(int j = 0; j < getNumberOfArguments(); j++)
/* 307*/ i |= super.argument[j].getDependencies();
/* 309*/ return i;
}
public Expression reduce(int i, Context context)
throws XPathException
{
/* 324*/ if((i & 0x38) != 0)
/* 327*/ return evaluate(context);
/* 331*/ FunctionProxy functionproxy = new FunctionProxy();
/* 332*/ functionproxy.theClass = theClass;
/* 333*/ functionproxy.candidateMethods = candidateMethods;
/* 334*/ functionproxy.theException = theException;
/* 335*/ functionproxy.name = name;
/* 336*/ functionproxy.argument = new Expression[getNumberOfArguments()];
/* 337*/ for(int j = 0; j < getNumberOfArguments(); j++)
/* 338*/ functionproxy.addArgument(super.argument[j].reduce(i, context));
/* 340*/ return functionproxy;
}
public Object getBestFit(Value avalue[])
throws XPathException
{
/* 353*/ if(candidateMethods.size() == 1)
/* 355*/ return candidateMethods.elementAt(0);
/* 361*/ int i = candidateMethods.size();
/* 362*/ boolean aflag[] = new boolean[i];
/* 363*/ for(int j = 0; j < i; j++)
/* 364*/ aflag[j] = false;
/* 367*/ for(int k = 0; k < i - 1; k++)
{
/* 368*/ int ai[] = getConversionPreferences(avalue, candidateMethods.elementAt(k));
/* 371*/ if(!aflag[k])
{
/* 372*/ for(int i1 = k + 1; i1 < i; i1++)
/* 373*/ if(!aflag[i1])
{
/* 374*/ int ai1[] = getConversionPreferences(avalue, candidateMethods.elementAt(i1));
/* 377*/ for(int k1 = 0; k1 < ai1.length; k1++)
{
/* 378*/ if(ai[k1] > ai1[k1])
/* 379*/ aflag[k] = true;
/* 381*/ if(ai[k1] < ai1[k1])
/* 382*/ aflag[i1] = true;
}
}
}
}
/* 390*/ int l = 0;
/* 391*/ Object obj = null;
/* 392*/ for(int j1 = 0; j1 < i; j1++)
/* 393*/ if(!aflag[j1])
{
/* 394*/ obj = candidateMethods.elementAt(j1);
/* 395*/ l++;
}
/* 399*/ if(l == 0)
/* 400*/ throw new XPathException("There is no Java method that is a unique best match");
/* 403*/ if(l > 1)
/* 404*/ throw new XPathException("There are several Java methods that match equally well");
/* 407*/ else
/* 407*/ return obj;
}
public Value evaluate(Context context)
throws XPathException
{
/* 419*/ Object obj = call(context);
/* 420*/ return convertJavaObjectToXPath(obj, context.getController());
}
public String evaluateAsString(Context context)
throws XPathException
{
/* 424*/ if(resultClass == (java.lang.String.class))
/* 425*/ return (String)call(context);
/* 426*/ if(resultClass == (com.icl.saxon.om.NodeEnumeration.class))
{
/* 427*/ NodeEnumeration nodeenumeration = enumerate(context, true);
/* 428*/ if(nodeenumeration.hasMoreElements())
/* 429*/ return nodeenumeration.nextElement().getStringValue();
/* 431*/ else
/* 431*/ return "";
} else
{
/* 434*/ return evaluate(context).asString();
}
}
public double evaluateAsNumber(Context context)
throws XPathException
{
/* 439*/ if(resultClass == Double.TYPE)
/* 440*/ return ((Double)call(context)).doubleValue();
/* 441*/ if(resultClass == (com.icl.saxon.om.NodeEnumeration.class))
{
/* 442*/ NodeEnumeration nodeenumeration = enumerate(context, true);
/* 443*/ if(nodeenumeration.hasMoreElements())
/* 444*/ return Value.stringToNumber(nodeenumeration.nextElement().getStringValue());
/* 446*/ else
/* 446*/ return (0.0D / 0.0D);
} else
{
/* 449*/ return evaluate(context).asNumber();
}
}
public boolean evaluateAsBoolean(Context context)
throws XPathException
{
/* 454*/ if(resultClass == Boolean.TYPE)
/* 455*/ return ((Boolean)call(context)).booleanValue();
/* 456*/ if(resultClass == (com.icl.saxon.om.NodeEnumeration.class))
{
/* 457*/ NodeEnumeration nodeenumeration = enumerate(context, false);
/* 458*/ return nodeenumeration.hasMoreElements();
} else
{
/* 460*/ return evaluate(context).asBoolean();
}
}
public NodeEnumeration enumerate(Context context, boolean flag)
throws XPathException
{
/* 465*/ if(resultClass == (com.icl.saxon.om.NodeEnumeration.class))
{
/* 466*/ NodeEnumeration nodeenumeration = (NodeEnumeration)call(context);
/* 467*/ if(flag && !nodeenumeration.isSorted())
{
/* 468*/ NodeSetExtent nodesetextent = new NodeSetExtent(nodeenumeration, context.getController());
/* 469*/ nodesetextent.sort();
/* 470*/ return nodesetextent.enumerate();
} else
{
/* 472*/ return nodeenumeration;
}
} else
{
/* 475*/ return super.enumerate(context, flag);
}
}
private Object call(Context context)
throws XPathException
{
/* 487*/ if(theException != null)
/* 488*/ throw theException;
/* 490*/ context.setException(null);
/* 492*/ Value avalue[] = new Value[getNumberOfArguments()];
/* 493*/ for(int i = 0; i < getNumberOfArguments(); i++)
/* 494*/ avalue[i] = super.argument[i].evaluate(context);
/* 499*/ Object obj = getBestFit(avalue);
/* 506*/ if(obj instanceof Constructor)
{
/* 507*/ Constructor constructor = (Constructor)obj;
/* 508*/ Class aclass[] = constructor.getParameterTypes();
/* 509*/ Object aobj[] = new Object[aclass.length];
/* 511*/ setupParams(avalue, aobj, aclass, 0, 0);
/* 514*/ try
{
/* 514*/ Object obj1 = constructor.newInstance(aobj);
/* 515*/ if(context.getException() != null)
/* 516*/ throw context.getException();
/* 518*/ else
/* 518*/ return obj1;
}
/* 521*/ catch(InstantiationException instantiationexception)
{
/* 521*/ throw new XPathException("Cannot instantiate class", instantiationexception);
}
/* 523*/ catch(IllegalAccessException illegalaccessexception)
{
/* 523*/ throw new XPathException("Constructor access is illegal", illegalaccessexception);
}
/* 525*/ catch(IllegalArgumentException illegalargumentexception)
{
/* 525*/ throw new XPathException("Argument is of wrong type", illegalargumentexception);
}
/* 527*/ catch(InvocationTargetException invocationtargetexception)
{
/* 527*/ Throwable throwable = invocationtargetexception.getTargetException();
/* 528*/ if(throwable instanceof XPathException)
/* 529*/ throw (XPathException)throwable;
/* 531*/ if(context.getController().isTracing())
/* 532*/ invocationtargetexception.getTargetException().printStackTrace();
/* 534*/ throw new XPathException("Exception in extension function " + invocationtargetexception.getTargetException().toString());
}
}
/* 539*/ Method method = (Method)obj;
/* 540*/ boolean flag = Modifier.isStatic(method.getModifiers());
/* 542*/ Class aclass1[] = method.getParameterTypes();
/* 543*/ boolean flag1 = aclass1.length > 0 && (aclass1[0] == (com.icl.saxon.Context.class) || aclass1[0] == (org.w3c.xsl.XSLTContext.class));
Object obj2;
/* 546*/ if(flag)
{
/* 547*/ obj2 = null;
} else
{
/* 549*/ int j = getNumberOfArguments();
/* 550*/ if(j == 0)
/* 551*/ throw new XPathException("Must supply an argument for an instance-level extension function");
/* 553*/ Value value = super.argument[0].evaluate(context);
/* 554*/ if(value instanceof ObjectValue)
/* 556*/ obj2 = ((ObjectValue)value).getObject();
/* 557*/ else
/* 557*/ if(theClass == (java.lang.String.class))
/* 558*/ obj2 = value.asString();
/* 559*/ else
/* 559*/ if(theClass == (java.lang.Boolean.class))
/* 560*/ obj2 = new Boolean(value.asBoolean());
/* 561*/ else
/* 561*/ if(theClass == (java.lang.Double.class))
/* 562*/ obj2 = new Double(value.asNumber());
/* 564*/ else
/* 564*/ throw new XPathException("First argument is not an object instance");
}
/* 569*/ int k = (aclass1.length - (flag1 ? 1 : 0)) + (flag ? 0 : 1);
/* 573*/ checkArgumentCount(k, k);
/* 574*/ Object aobj1[] = new Object[aclass1.length];
/* 576*/ if(flag1)
/* 577*/ aobj1[0] = context;
/* 580*/ setupParams(avalue, aobj1, aclass1, flag1 ? 1 : 0, flag ? 0 : 1);
/* 586*/ try
{
/* 586*/ Object obj3 = method.invoke(obj2, aobj1);
/* 587*/ if(context.getException() != null)
/* 588*/ throw context.getException();
/* 590*/ if(method.getReturnType().toString().equals("void"))
/* 593*/ return new EmptyNodeSet();
/* 595*/ else
/* 595*/ return obj3;
}
/* 598*/ catch(IllegalAccessException illegalaccessexception1)
{
/* 598*/ throw new XPathException("Method access is illegal", illegalaccessexception1);
}
/* 600*/ catch(IllegalArgumentException illegalargumentexception1)
{
/* 600*/ throw new XPathException("Argument is of wrong type", illegalargumentexception1);
}
/* 602*/ catch(InvocationTargetException invocationtargetexception1)
{
/* 602*/ Throwable throwable1 = invocationtargetexception1.getTargetException();
/* 603*/ if(throwable1 instanceof XPathException)
/* 604*/ throw (XPathException)throwable1;
/* 606*/ if(context.getController().isTracing())
/* 607*/ invocationtargetexception1.getTargetException().printStackTrace();
/* 609*/ throw new XPathException("Exception in extension function " + invocationtargetexception1.getTargetException().toString());
}
}
public static Value convertJavaObjectToXPath(Object obj, Controller controller)
throws XPathException
{
/* 624*/ if(obj == null)
/* 625*/ return new ObjectValue(null);
/* 627*/ if(obj instanceof String)
/* 628*/ return new StringValue((String)obj);
/* 630*/ if(obj instanceof Boolean)
/* 631*/ return new BooleanValue(((Boolean)obj).booleanValue());
/* 633*/ if(obj instanceof Double)
/* 634*/ return new NumericValue(((Double)obj).doubleValue());
/* 635*/ if(obj instanceof Float)
/* 636*/ return new NumericValue(((Float)obj).floatValue());
/* 637*/ if(obj instanceof Short)
/* 638*/ return new NumericValue(((Short)obj).shortValue());
/* 639*/ if(obj instanceof Integer)
/* 640*/ return new NumericValue(((Integer)obj).intValue());
/* 641*/ if(obj instanceof Long)
/* 642*/ return new NumericValue(((Long)obj).longValue());
/* 643*/ if(obj instanceof Character)
/* 644*/ return new NumericValue(((Character)obj).charValue());
/* 645*/ if(obj instanceof Byte)
/* 646*/ return new NumericValue(((Byte)obj).byteValue());
/* 648*/ if(obj instanceof Value)
/* 649*/ return (Value)obj;
/* 651*/ if(obj instanceof NodeInfo)
/* 652*/ return new SingletonNodeSet((NodeInfo)obj);
/* 653*/ if(obj instanceof NodeEnumeration)
/* 656*/ return new NodeSetExtent((NodeEnumeration)obj, controller);
/* 658*/ if(obj instanceof NodeList)
{
/* 659*/ NodeList nodelist = (NodeList)obj;
/* 660*/ NodeInfo anodeinfo[] = new NodeInfo[nodelist.getLength()];
/* 661*/ for(int i = 0; i < nodelist.getLength(); i++)
/* 662*/ if(nodelist.item(i) instanceof NodeInfo)
/* 663*/ anodeinfo[i] = (NodeInfo)nodelist.item(i);
/* 665*/ else
/* 665*/ throw new XPathException("Supplied NodeList contains non-Saxon DOM Nodes");
/* 669*/ return new NodeSetExtent(anodeinfo, controller);
}
/* 670*/ if(obj instanceof Node)
/* 671*/ throw new XPathException("Result is a non-Saxon DOM Node");
/* 673*/ else
/* 673*/ return new ObjectValue(obj);
}
private int[] getConversionPreferences(Value avalue[], Object obj)
{
Class aclass[];
int i;
/* 691*/ if(obj instanceof Constructor)
{
/* 692*/ i = 0;
/* 693*/ aclass = ((Constructor)obj).getParameterTypes();
} else
{
/* 695*/ boolean flag = Modifier.isStatic(((Method)obj).getModifiers());
/* 696*/ i = flag ? 0 : 1;
/* 697*/ aclass = ((Method)obj).getParameterTypes();
}
/* 700*/ int ai[] = new int[avalue.length];
/* 701*/ if(i == 1)
/* 702*/ ai[0] = (avalue[0] instanceof ObjectValue) ? 0 : 20;
/* 704*/ int j = 0;
/* 706*/ if(aclass[0] == (com.icl.saxon.Context.class) || aclass[0] == (org.w3c.xsl.XSLTContext.class))
/* 707*/ j = 1;
/* 710*/ for(int k = i; k < avalue.length; k++)
/* 711*/ ai[k] = avalue[k - i].conversionPreference(aclass[(k + j) - i]);
/* 714*/ return ai;
}
private void setupParams(Value avalue[], Object aobj[], Class aclass[], int i, int j)
throws XPathException
{
/* 723*/ int k = i;
/* 724*/ for(int l = j; l < getNumberOfArguments(); l++)
{
/* 725*/ aobj[k] = avalue[l].convertToJava(aclass[k]);
/* 726*/ k++;
}
}
}