1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.lang.reflect.Constructor ; 23 import java.lang.reflect.Method ; 24 import java.lang.reflect.Modifier ; 25 import java.util.Enumeration ; 26 import java.util.Hashtable ; 27 import java.util.Vector ; 28 29 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 30 import com.sun.org.apache.bcel.internal.generic.IFEQ; 31 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 32 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 33 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; 34 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 35 import com.sun.org.apache.bcel.internal.generic.InstructionConstants; 36 import com.sun.org.apache.bcel.internal.generic.InstructionList; 37 import com.sun.org.apache.bcel.internal.generic.InvokeInstruction; 38 import com.sun.org.apache.bcel.internal.generic.NEW; 39 import com.sun.org.apache.bcel.internal.generic.PUSH; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.IntType; 44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 45 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType; 46 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MultiHashtable; 47 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ObjectType; 48 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType; 49 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 50 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 51 52 59 class FunctionCall extends Expression { 60 61 private QName _fname; 63 private final Vector _arguments; 65 private final static Vector EMPTY_ARG_LIST = new Vector (0); 67 68 protected final static String EXT_XSLTC = 70 TRANSLET_URI; 71 72 protected final static String JAVA_EXT_XSLTC = 73 EXT_XSLTC + "/java"; 74 75 protected final static String EXT_XALAN = 76 "http://xml.apache.org/xalan"; 77 78 protected final static String JAVA_EXT_XALAN = 79 "http://xml.apache.org/xalan/java"; 80 81 protected final static String JAVA_EXT_XALAN_OLD = 82 "http://xml.apache.org/xslt/java"; 83 84 protected final static String EXSLT_COMMON = 85 "http://exslt.org/common"; 86 87 protected final static String EXSLT_MATH = 88 "http://exslt.org/math"; 89 90 protected final static String EXSLT_SETS = 91 "http://exslt.org/sets"; 92 93 protected final static String EXSLT_DATETIME = 94 "http://exslt.org/dates-and-times"; 95 96 protected final static String EXSLT_STRINGS = 97 "http://exslt.org/strings"; 98 99 protected final static int NAMESPACE_FORMAT_JAVA = 0; 101 protected final static int NAMESPACE_FORMAT_CLASS = 1; 102 protected final static int NAMESPACE_FORMAT_PACKAGE = 2; 103 protected final static int NAMESPACE_FORMAT_CLASS_OR_PACKAGE = 3; 104 105 private int _namespace_format = NAMESPACE_FORMAT_JAVA; 107 108 111 Expression _thisArgument = null; 112 113 private String _className; 115 private Class _clazz; 116 private Method _chosenMethod; 117 private Constructor _chosenConstructor; 118 private MethodType _chosenMethodType; 119 120 private boolean unresolvedExternal; 122 123 private boolean _isExtConstructor = false; 125 126 private boolean _isStatic = false; 128 129 private static final MultiHashtable _internal2Java = new MultiHashtable(); 131 132 private static final Hashtable _java2Internal = new Hashtable (); 134 135 private static final Hashtable _extensionNamespaceTable = new Hashtable (); 137 138 private static final Hashtable _extensionFunctionTable = new Hashtable (); 140 145 static class JavaType { 146 public Class type; 147 public int distance; 148 149 public JavaType(Class type, int distance){ 150 this.type = type; 151 this.distance = distance; 152 } 153 public boolean equals(Object query){ 154 return query.equals(type); 155 } 156 } 157 158 164 static { 165 try { 166 final Class nodeClass = Class.forName("org.w3c.dom.Node"); 167 final Class nodeListClass = Class.forName("org.w3c.dom.NodeList"); 168 169 171 _internal2Java.put(Type.Boolean, new JavaType(Boolean.TYPE, 0)); 173 _internal2Java.put(Type.Boolean, new JavaType(Boolean .class, 1)); 174 _internal2Java.put(Type.Boolean, new JavaType(Object .class, 2)); 175 176 _internal2Java.put(Type.Real, new JavaType(Double.TYPE, 0)); 179 _internal2Java.put(Type.Real, new JavaType(Double .class, 1)); 180 _internal2Java.put(Type.Real, new JavaType(Float.TYPE, 2)); 181 _internal2Java.put(Type.Real, new JavaType(Long.TYPE, 3)); 182 _internal2Java.put(Type.Real, new JavaType(Integer.TYPE, 4)); 183 _internal2Java.put(Type.Real, new JavaType(Short.TYPE, 5)); 184 _internal2Java.put(Type.Real, new JavaType(Byte.TYPE, 6)); 185 _internal2Java.put(Type.Real, new JavaType(Character.TYPE, 7)); 186 _internal2Java.put(Type.Real, new JavaType(Object .class, 8)); 187 188 _internal2Java.put(Type.Int, new JavaType(Double.TYPE, 0)); 190 _internal2Java.put(Type.Int, new JavaType(Double .class, 1)); 191 _internal2Java.put(Type.Int, new JavaType(Float.TYPE, 2)); 192 _internal2Java.put(Type.Int, new JavaType(Long.TYPE, 3)); 193 _internal2Java.put(Type.Int, new JavaType(Integer.TYPE, 4)); 194 _internal2Java.put(Type.Int, new JavaType(Short.TYPE, 5)); 195 _internal2Java.put(Type.Int, new JavaType(Byte.TYPE, 6)); 196 _internal2Java.put(Type.Int, new JavaType(Character.TYPE, 7)); 197 _internal2Java.put(Type.Int, new JavaType(Object .class, 8)); 198 199 _internal2Java.put(Type.String, new JavaType(String .class, 0)); 201 _internal2Java.put(Type.String, new JavaType(Object .class, 1)); 202 203 _internal2Java.put(Type.NodeSet, new JavaType(nodeListClass, 0)); 205 _internal2Java.put(Type.NodeSet, new JavaType(nodeClass, 1)); 206 _internal2Java.put(Type.NodeSet, new JavaType(Object .class, 2)); 207 _internal2Java.put(Type.NodeSet, new JavaType(String .class, 3)); 208 209 _internal2Java.put(Type.Node, new JavaType(nodeListClass, 0)); 211 _internal2Java.put(Type.Node, new JavaType(nodeClass, 1)); 212 _internal2Java.put(Type.Node, new JavaType(Object .class, 2)); 213 _internal2Java.put(Type.Node, new JavaType(String .class, 3)); 214 215 _internal2Java.put(Type.ResultTree, new JavaType(nodeListClass, 0)); 217 _internal2Java.put(Type.ResultTree, new JavaType(nodeClass, 1)); 218 _internal2Java.put(Type.ResultTree, new JavaType(Object .class, 2)); 219 _internal2Java.put(Type.ResultTree, new JavaType(String .class, 3)); 220 221 _internal2Java.put(Type.Reference, new JavaType(Object .class, 0)); 222 223 _java2Internal.put(Boolean.TYPE, Type.Boolean); 225 _java2Internal.put(Void.TYPE, Type.Void); 226 _java2Internal.put(Character.TYPE, Type.Real); 227 _java2Internal.put(Byte.TYPE, Type.Real); 228 _java2Internal.put(Short.TYPE, Type.Real); 229 _java2Internal.put(Integer.TYPE, Type.Real); 230 _java2Internal.put(Long.TYPE, Type.Real); 231 _java2Internal.put(Float.TYPE, Type.Real); 232 _java2Internal.put(Double.TYPE, Type.Real); 233 234 _java2Internal.put(String .class, Type.String); 235 236 _java2Internal.put(Object .class, Type.Reference); 237 238 _java2Internal.put(nodeListClass, Type.NodeSet); 240 _java2Internal.put(nodeClass, Type.NodeSet); 241 242 _extensionNamespaceTable.put(EXT_XALAN, "com.sun.org.apache.xalan.internal.lib.Extensions"); 244 _extensionNamespaceTable.put(EXSLT_COMMON, "com.sun.org.apache.xalan.internal.lib.ExsltCommon"); 245 _extensionNamespaceTable.put(EXSLT_MATH, "com.sun.org.apache.xalan.internal.lib.ExsltMath"); 246 _extensionNamespaceTable.put(EXSLT_SETS, "com.sun.org.apache.xalan.internal.lib.ExsltSets"); 247 _extensionNamespaceTable.put(EXSLT_DATETIME, "com.sun.org.apache.xalan.internal.lib.ExsltDatetime"); 248 _extensionNamespaceTable.put(EXSLT_STRINGS, "com.sun.org.apache.xalan.internal.lib.ExsltStrings"); 249 250 _extensionFunctionTable.put(EXSLT_COMMON + ":nodeSet", "nodeset"); 252 _extensionFunctionTable.put(EXSLT_COMMON + ":objectType", "objectType"); 253 _extensionFunctionTable.put(EXT_XALAN + ":nodeset", "nodeset"); 254 } 255 catch (ClassNotFoundException e) { 256 System.err.println(e); 257 } 258 } 259 260 public FunctionCall(QName fname, Vector arguments) { 261 _fname = fname; 262 _arguments = arguments; 263 _type = null; 264 } 265 266 public FunctionCall(QName fname) { 267 this(fname, EMPTY_ARG_LIST); 268 } 269 270 public String getName() { 271 return(_fname.toString()); 272 } 273 274 public void setParser(Parser parser) { 275 super.setParser(parser); 276 if (_arguments != null) { 277 final int n = _arguments.size(); 278 for (int i = 0; i < n; i++) { 279 final Expression exp = (Expression)_arguments.elementAt(i); 280 exp.setParser(parser); 281 exp.setParent(this); 282 } 283 } 284 } 285 286 public String getClassNameFromUri(String uri) 287 { 288 String className = (String )_extensionNamespaceTable.get(uri); 289 290 if (className != null) 291 return className; 292 else { 293 if (uri.startsWith(JAVA_EXT_XSLTC)) { 294 int length = JAVA_EXT_XSLTC.length() + 1; 295 return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING; 296 } 297 else if (uri.startsWith(JAVA_EXT_XALAN)) { 298 int length = JAVA_EXT_XALAN.length() + 1; 299 return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING; 300 } 301 else if (uri.startsWith(JAVA_EXT_XALAN_OLD)) { 302 int length = JAVA_EXT_XALAN_OLD.length() + 1; 303 return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING; 304 } 305 else { 306 int index = uri.lastIndexOf('/'); 307 return (index > 0) ? uri.substring(index+1) : uri; 308 } 309 } 310 } 311 312 316 public Type typeCheck(SymbolTable stable) 317 throws TypeCheckError 318 { 319 if (_type != null) return _type; 320 321 final String namespace = _fname.getNamespace(); 322 String local = _fname.getLocalPart(); 323 324 if (isExtension()) { 325 _fname = new QName(null, null, local); 326 return typeCheckStandard(stable); 327 } 328 else if (isStandard()) { 329 return typeCheckStandard(stable); 330 } 331 else { 333 try { 334 _className = getClassNameFromUri(namespace); 335 336 final int pos = local.lastIndexOf('.'); 337 if (pos > 0) { 338 _isStatic = true; 339 if (_className != null && _className.length() > 0) { 340 _namespace_format = NAMESPACE_FORMAT_PACKAGE; 341 _className = _className + "." + local.substring(0, pos); 342 } 343 else { 344 _namespace_format = NAMESPACE_FORMAT_JAVA; 345 _className = local.substring(0, pos); 346 } 347 348 _fname = new QName(namespace, null, local.substring(pos + 1)); 349 } 350 else { 351 if (_className != null && _className.length() > 0) { 352 try { 353 _clazz = ObjectFactory.findProviderClass( 354 _className, ObjectFactory.findClassLoader(), true); 355 _namespace_format = NAMESPACE_FORMAT_CLASS; 356 } 357 catch (ClassNotFoundException e) { 358 _namespace_format = NAMESPACE_FORMAT_PACKAGE; 359 } 360 } 361 else 362 _namespace_format = NAMESPACE_FORMAT_JAVA; 363 364 if (local.indexOf('-') > 0) { 365 local = replaceDash(local); 366 } 367 368 String extFunction = (String )_extensionFunctionTable.get(namespace + ":" + local); 369 if (extFunction != null) { 370 _fname = new QName(null, null, extFunction); 371 return typeCheckStandard(stable); 372 } 373 else 374 _fname = new QName(namespace, null, local); 375 } 376 377 return typeCheckExternal(stable); 378 } 379 catch (TypeCheckError e) { 380 ErrorMsg errorMsg = e.getErrorMsg(); 381 if (errorMsg == null) { 382 final String name = _fname.getLocalPart(); 383 errorMsg = new ErrorMsg(ErrorMsg.METHOD_NOT_FOUND_ERR, name); 384 } 385 getParser().reportError(ERROR, errorMsg); 386 return _type = Type.Void; 387 } 388 } 389 } 390 391 396 public Type typeCheckStandard(SymbolTable stable) throws TypeCheckError { 397 _fname.clearNamespace(); 399 final int n = _arguments.size(); 400 final Vector argsType = typeCheckArgs(stable); 401 final MethodType args = new MethodType(Type.Void, argsType); 402 final MethodType ptype = 403 lookupPrimop(stable, _fname.getLocalPart(), args); 404 405 if (ptype != null) { 406 for (int i = 0; i < n; i++) { 407 final Type argType = (Type) ptype.argsType().elementAt(i); 408 final Expression exp = (Expression)_arguments.elementAt(i); 409 if (!argType.identicalTo(exp.getType())) { 410 try { 411 _arguments.setElementAt(new CastExpr(exp, argType), i); 412 } 413 catch (TypeCheckError e) { 414 throw new TypeCheckError(this); } 416 } 417 } 418 _chosenMethodType = ptype; 419 return _type = ptype.resultType(); 420 } 421 throw new TypeCheckError(this); 422 } 423 424 425 426 public Type typeCheckConstructor(SymbolTable stable) throws TypeCheckError{ 427 final Vector constructors = findConstructors(); 428 if (constructors == null) { 429 throw new TypeCheckError(ErrorMsg.CONSTRUCTOR_NOT_FOUND, 431 _className); 432 433 } 434 435 final int nConstructors = constructors.size(); 436 final int nArgs = _arguments.size(); 437 final Vector argsType = typeCheckArgs(stable); 438 439 int bestConstrDistance = Integer.MAX_VALUE; 441 _type = null; for (int j, i = 0; i < nConstructors; i++) { 443 final Constructor constructor = 445 (Constructor )constructors.elementAt(i); 446 final Class [] paramTypes = constructor.getParameterTypes(); 447 448 Class extType = null; 449 int currConstrDistance = 0; 450 for (j = 0; j < nArgs; j++) { 451 extType = paramTypes[j]; 453 final Type intType = (Type)argsType.elementAt(j); 454 Object match = _internal2Java.maps(intType, extType); 455 if (match != null) { 456 currConstrDistance += ((JavaType)match).distance; 457 } 458 else if (intType instanceof ObjectType) { 459 ObjectType objectType = (ObjectType)intType; 460 if (objectType.getJavaClass() == extType) 461 continue; 462 else if (extType.isAssignableFrom(objectType.getJavaClass())) 463 currConstrDistance += 1; 464 else { 465 currConstrDistance = Integer.MAX_VALUE; 466 break; 467 } 468 } 469 else { 470 currConstrDistance = Integer.MAX_VALUE; 472 break; 473 } 474 } 475 476 if (j == nArgs && currConstrDistance < bestConstrDistance ) { 477 _chosenConstructor = constructor; 478 _isExtConstructor = true; 479 bestConstrDistance = currConstrDistance; 480 481 _type = (_clazz != null) ? Type.newObjectType(_clazz) 482 : Type.newObjectType(_className); 483 } 484 } 485 486 if (_type != null) { 487 return _type; 488 } 489 490 throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR, getMethodSignature(argsType)); 491 } 492 493 494 501 public Type typeCheckExternal(SymbolTable stable) throws TypeCheckError { 502 int nArgs = _arguments.size(); 503 final String name = _fname.getLocalPart(); 504 505 if (_fname.getLocalPart().equals("new")) { 507 return typeCheckConstructor(stable); 508 } 509 else { 511 boolean hasThisArgument = false; 512 513 if (nArgs == 0) 514 _isStatic = true; 515 516 if (!_isStatic) { 517 if (_namespace_format == NAMESPACE_FORMAT_JAVA 518 || _namespace_format == NAMESPACE_FORMAT_PACKAGE) 519 hasThisArgument = true; 520 521 Expression firstArg = (Expression)_arguments.elementAt(0); 522 Type firstArgType = (Type)firstArg.typeCheck(stable); 523 524 if (_namespace_format == NAMESPACE_FORMAT_CLASS 525 && firstArgType instanceof ObjectType 526 && _clazz != null 527 && _clazz.isAssignableFrom(((ObjectType)firstArgType).getJavaClass())) 528 hasThisArgument = true; 529 530 if (hasThisArgument) { 531 _thisArgument = (Expression) _arguments.elementAt(0); 532 _arguments.remove(0); nArgs--; 533 if (firstArgType instanceof ObjectType) { 534 _className = ((ObjectType) firstArgType).getJavaClassName(); 535 } 536 else 537 throw new TypeCheckError(ErrorMsg.NO_JAVA_FUNCT_THIS_REF, name); 538 } 539 } 540 else if (_className.length() == 0) { 541 547 final Parser parser = getParser(); 548 if (parser != null) { 549 reportWarning(this, parser, ErrorMsg.FUNCTION_RESOLVE_ERR, 550 _fname.toString()); 551 } 552 unresolvedExternal = true; 553 return _type = Type.Int; } 555 } 556 557 final Vector methods = findMethods(); 558 559 if (methods == null) { 560 throw new TypeCheckError(ErrorMsg.METHOD_NOT_FOUND_ERR, _className + "." + name); 562 } 563 564 Class extType = null; 565 final int nMethods = methods.size(); 566 final Vector argsType = typeCheckArgs(stable); 567 568 int bestMethodDistance = Integer.MAX_VALUE; 570 _type = null; for (int j, i = 0; i < nMethods; i++) { 572 final Method method = (Method )methods.elementAt(i); 574 final Class [] paramTypes = method.getParameterTypes(); 575 576 int currMethodDistance = 0; 577 for (j = 0; j < nArgs; j++) { 578 extType = paramTypes[j]; 580 final Type intType = (Type)argsType.elementAt(j); 581 Object match = _internal2Java.maps(intType, extType); 582 if (match != null) { 583 currMethodDistance += ((JavaType)match).distance; 584 } 585 else { 586 if (intType instanceof ReferenceType) { 591 currMethodDistance += 1; 592 } 593 else if (intType instanceof ObjectType) { 594 ObjectType object = (ObjectType)intType; 595 if (extType.getName().equals(object.getJavaClassName())) 596 currMethodDistance += 0; 597 else if (extType.isAssignableFrom(object.getJavaClass())) 598 currMethodDistance += 1; 599 else { 600 currMethodDistance = Integer.MAX_VALUE; 601 break; 602 } 603 } 604 else { 605 currMethodDistance = Integer.MAX_VALUE; 606 break; 607 } 608 } 609 } 610 611 if (j == nArgs) { 612 extType = method.getReturnType(); 614 615 _type = (Type) _java2Internal.get(extType); 616 if (_type == null) { 617 _type = Type.newObjectType(extType); 618 } 619 620 if (_type != null && currMethodDistance < bestMethodDistance) { 622 _chosenMethod = method; 623 bestMethodDistance = currMethodDistance; 624 } 625 } 626 } 627 628 if (_chosenMethod != null && _thisArgument == null && 631 !Modifier.isStatic(_chosenMethod.getModifiers())) { 632 throw new TypeCheckError(ErrorMsg.NO_JAVA_FUNCT_THIS_REF, getMethodSignature(argsType)); 633 } 634 635 if (_type != null) { 636 if (_type == Type.NodeSet) { 637 getXSLTC().setMultiDocument(true); 638 } 639 return _type; 640 } 641 642 throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR, getMethodSignature(argsType)); 643 } 644 645 648 public Vector typeCheckArgs(SymbolTable stable) throws TypeCheckError { 649 final Vector result = new Vector (); 650 final Enumeration e = _arguments.elements(); 651 while (e.hasMoreElements()) { 652 final Expression exp = (Expression)e.nextElement(); 653 result.addElement(exp.typeCheck(stable)); 654 } 655 return result; 656 } 657 658 protected final Expression argument(int i) { 659 return (Expression)_arguments.elementAt(i); 660 } 661 662 protected final Expression argument() { 663 return argument(0); 664 } 665 666 protected final int argumentCount() { 667 return _arguments.size(); 668 } 669 670 protected final void setArgument(int i, Expression exp) { 671 _arguments.setElementAt(exp, i); 672 } 673 674 678 public void translateDesynthesized(ClassGenerator classGen, 679 MethodGenerator methodGen) 680 { 681 Type type = Type.Boolean; 682 if (_chosenMethodType != null) 683 type = _chosenMethodType.resultType(); 684 685 final InstructionList il = methodGen.getInstructionList(); 686 translate(classGen, methodGen); 687 688 if ((type instanceof BooleanType) || (type instanceof IntType)) { 689 _falseList.add(il.append(new IFEQ(null))); 690 } 691 } 692 693 694 698 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 699 final int n = argumentCount(); 700 final ConstantPoolGen cpg = classGen.getConstantPool(); 701 final InstructionList il = methodGen.getInstructionList(); 702 final boolean isSecureProcessing = classGen.getParser().getXSLTC().isSecureProcessing(); 703 int index; 704 705 if (isStandard() || isExtension()) { 707 for (int i = 0; i < n; i++) { 708 final Expression exp = argument(i); 709 exp.translate(classGen, methodGen); 710 exp.startIterator(classGen, methodGen); 711 } 712 713 final String name = _fname.toString().replace('-', '_') + "F"; 715 String args = Constants.EMPTYSTRING; 716 717 if (name.equals("sumF")) { 719 args = DOM_INTF_SIG; 720 il.append(methodGen.loadDOM()); 721 } 722 else if (name.equals("normalize_spaceF")) { 723 if (_chosenMethodType.toSignature(args). 724 equals("()Ljava/lang/String;")) { 725 args = "I"+DOM_INTF_SIG; 726 il.append(methodGen.loadContextNode()); 727 il.append(methodGen.loadDOM()); 728 } 729 } 730 731 index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name, 733 _chosenMethodType.toSignature(args)); 734 il.append(new INVOKESTATIC(index)); 735 } 736 else if (unresolvedExternal) { 739 index = cpg.addMethodref(BASIS_LIBRARY_CLASS, 740 "unresolved_externalF", 741 "(Ljava/lang/String;)V"); 742 il.append(new PUSH(cpg, _fname.toString())); 743 il.append(new INVOKESTATIC(index)); 744 } 745 else if (_isExtConstructor) { 746 if (isSecureProcessing) 747 translateUnallowedExtension(cpg, il); 748 749 final String clazz = 750 _chosenConstructor.getDeclaringClass().getName(); 751 Class [] paramTypes = _chosenConstructor.getParameterTypes(); 752 753 il.append(new NEW(cpg.addClass(_className))); 754 il.append(InstructionConstants.DUP); 755 756 for (int i = 0; i < n; i++) { 757 final Expression exp = argument(i); 758 exp.translate(classGen, methodGen); 759 exp.startIterator(classGen, methodGen); 761 exp.getType().translateTo(classGen, methodGen, paramTypes[i]); 762 } 763 764 final StringBuffer buffer = new StringBuffer (); 765 buffer.append('('); 766 for (int i = 0; i < paramTypes.length; i++) { 767 buffer.append(getSignature(paramTypes[i])); 768 } 769 buffer.append(')'); 770 buffer.append("V"); 771 772 index = cpg.addMethodref(clazz, 773 "<init>", 774 buffer.toString()); 775 il.append(new INVOKESPECIAL(index)); 776 777 (Type.Object).translateFrom(classGen, methodGen, 779 _chosenConstructor.getDeclaringClass()); 780 781 } 782 else { 784 if (isSecureProcessing) 785 translateUnallowedExtension(cpg, il); 786 787 final String clazz = _chosenMethod.getDeclaringClass().getName(); 788 Class [] paramTypes = _chosenMethod.getParameterTypes(); 789 790 if (_thisArgument != null) { 792 _thisArgument.translate(classGen, methodGen); 793 } 794 795 for (int i = 0; i < n; i++) { 796 final Expression exp = argument(i); 797 exp.translate(classGen, methodGen); 798 exp.startIterator(classGen, methodGen); 800 exp.getType().translateTo(classGen, methodGen, paramTypes[i]); 801 } 802 803 final StringBuffer buffer = new StringBuffer (); 804 buffer.append('('); 805 for (int i = 0; i < paramTypes.length; i++) { 806 buffer.append(getSignature(paramTypes[i])); 807 } 808 buffer.append(')'); 809 buffer.append(getSignature(_chosenMethod.getReturnType())); 810 811 if (_thisArgument != null && _clazz.isInterface()) { 812 index = cpg.addInterfaceMethodref(clazz, 813 _fname.getLocalPart(), 814 buffer.toString()); 815 il.append(new INVOKEINTERFACE(index, n+1)); 816 } 817 else { 818 index = cpg.addMethodref(clazz, 819 _fname.getLocalPart(), 820 buffer.toString()); 821 il.append(_thisArgument != null ? (InvokeInstruction) new INVOKEVIRTUAL(index) : 822 (InvokeInstruction) new INVOKESTATIC(index)); 823 } 824 825 _type.translateFrom(classGen, methodGen, 827 _chosenMethod.getReturnType()); 828 } 829 } 830 831 public String toString() { 832 return "funcall(" + _fname + ", " + _arguments + ')'; 833 } 834 835 public boolean isStandard() { 836 final String namespace = _fname.getNamespace(); 837 return (namespace == null) || (namespace.equals(Constants.EMPTYSTRING)); 838 } 839 840 public boolean isExtension() { 841 final String namespace = _fname.getNamespace(); 842 return (namespace != null) && (namespace.equals(EXT_XSLTC)); 843 } 844 845 850 private Vector findMethods() { 851 852 Vector result = null; 853 final String namespace = _fname.getNamespace(); 854 855 if (_className != null && _className.length() > 0) { 856 final int nArgs = _arguments.size(); 857 try { 858 if (_clazz == null) { 859 _clazz = ObjectFactory.findProviderClass( 860 _className, ObjectFactory.findClassLoader(), true); 861 862 if (_clazz == null) { 863 final ErrorMsg msg = 864 new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); 865 getParser().reportError(Constants.ERROR, msg); 866 } 867 } 868 869 final String methodName = _fname.getLocalPart(); 870 final Method [] methods = _clazz.getMethods(); 871 872 for (int i = 0; i < methods.length; i++) { 873 final int mods = methods[i].getModifiers(); 874 if (Modifier.isPublic(mods) 876 && methods[i].getName().equals(methodName) 877 && methods[i].getParameterTypes().length == nArgs) 878 { 879 if (result == null) { 880 result = new Vector (); 881 } 882 result.addElement(methods[i]); 883 } 884 } 885 } 886 catch (ClassNotFoundException e) { 887 final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); 888 getParser().reportError(Constants.ERROR, msg); 889 } 890 } 891 return result; 892 } 893 894 899 private Vector findConstructors() { 900 Vector result = null; 901 final String namespace = _fname.getNamespace(); 902 903 final int nArgs = _arguments.size(); 904 try { 905 if (_clazz == null) { 906 _clazz = ObjectFactory.findProviderClass( 907 _className, ObjectFactory.findClassLoader(), true); 908 909 if (_clazz == null) { 910 final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); 911 getParser().reportError(Constants.ERROR, msg); 912 } 913 } 914 915 final Constructor [] constructors = _clazz.getConstructors(); 916 917 for (int i = 0; i < constructors.length; i++) { 918 final int mods = constructors[i].getModifiers(); 919 if (Modifier.isPublic(mods) && 921 constructors[i].getParameterTypes().length == nArgs) 922 { 923 if (result == null) { 924 result = new Vector (); 925 } 926 result.addElement(constructors[i]); 927 } 928 } 929 } 930 catch (ClassNotFoundException e) { 931 final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); 932 getParser().reportError(Constants.ERROR, msg); 933 } 934 935 return result; 936 } 937 938 939 942 static final String getSignature(Class clazz) { 943 if (clazz.isArray()) { 944 final StringBuffer sb = new StringBuffer (); 945 Class cl = clazz; 946 while (cl.isArray()) { 947 sb.append("["); 948 cl = cl.getComponentType(); 949 } 950 sb.append(getSignature(cl)); 951 return sb.toString(); 952 } 953 else if (clazz.isPrimitive()) { 954 if (clazz == Integer.TYPE) { 955 return "I"; 956 } 957 else if (clazz == Byte.TYPE) { 958 return "B"; 959 } 960 else if (clazz == Long.TYPE) { 961 return "J"; 962 } 963 else if (clazz == Float.TYPE) { 964 return "F"; 965 } 966 else if (clazz == Double.TYPE) { 967 return "D"; 968 } 969 else if (clazz == Short.TYPE) { 970 return "S"; 971 } 972 else if (clazz == Character.TYPE) { 973 return "C"; 974 } 975 else if (clazz == Boolean.TYPE) { 976 return "Z"; 977 } 978 else if (clazz == Void.TYPE) { 979 return "V"; 980 } 981 else { 982 final String name = clazz.toString(); 983 ErrorMsg err = new ErrorMsg(ErrorMsg.UNKNOWN_SIG_TYPE_ERR,name); 984 throw new Error (err.toString()); 985 } 986 } 987 else { 988 return "L" + clazz.getName().replace('.', '/') + ';'; 989 } 990 } 991 992 995 static final String getSignature(Method meth) { 996 final StringBuffer sb = new StringBuffer (); 997 sb.append('('); 998 final Class [] params = meth.getParameterTypes(); for (int j = 0; j < params.length; j++) { 1000 sb.append(getSignature(params[j])); 1001 } 1002 return sb.append(')').append(getSignature(meth.getReturnType())) 1003 .toString(); 1004 } 1005 1006 1009 static final String getSignature(Constructor cons) { 1010 final StringBuffer sb = new StringBuffer (); 1011 sb.append('('); 1012 final Class [] params = cons.getParameterTypes(); for (int j = 0; j < params.length; j++) { 1014 sb.append(getSignature(params[j])); 1015 } 1016 return sb.append(")V").toString(); 1017 } 1018 1019 1022 private String getMethodSignature(Vector argsType) { 1023 final StringBuffer buf = new StringBuffer (_className); 1024 buf.append('.').append(_fname.getLocalPart()).append('('); 1025 1026 int nArgs = argsType.size(); 1027 for (int i = 0; i < nArgs; i++) { 1028 final Type intType = (Type)argsType.elementAt(i); 1029 buf.append(intType.toString()); 1030 if (i < nArgs - 1) buf.append(", "); 1031 } 1032 1033 buf.append(')'); 1034 return buf.toString(); 1035 } 1036 1037 1042 protected static String replaceDash(String name) 1043 { 1044 char dash = '-'; 1045 StringBuffer buff = new StringBuffer (""); 1046 for (int i = 0; i < name.length(); i++) { 1047 if (i > 0 && name.charAt(i-1) == dash) 1048 buff.append(Character.toUpperCase(name.charAt(i))); 1049 else if (name.charAt(i) != dash) 1050 buff.append(name.charAt(i)); 1051 } 1052 return buff.toString(); 1053 } 1054 1055 1059 private void translateUnallowedExtension(ConstantPoolGen cpg, 1060 InstructionList il) { 1061 int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, 1062 "unallowed_extension_functionF", 1063 "(Ljava/lang/String;)V"); 1064 il.append(new PUSH(cpg, _fname.toString())); 1065 il.append(new INVOKESTATIC(index)); 1066 } 1067} 1068 | Popular Tags |