📄 functioncall.java
字号:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: FunctionCall.java,v 1.2.4.1 2005/09/12 10:31:32 pvedula Exp $ */package com.sun.org.apache.xalan.internal.xsltc.compiler;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;import com.sun.org.apache.bcel.internal.generic.IFEQ;import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;import com.sun.org.apache.bcel.internal.generic.InstructionConstants;import com.sun.org.apache.bcel.internal.generic.InstructionList;import com.sun.org.apache.bcel.internal.generic.InvokeInstruction;import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;import com.sun.org.apache.bcel.internal.generic.NEW;import com.sun.org.apache.bcel.internal.generic.PUSH;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.IntType;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MultiHashtable;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ObjectType;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;/** * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen * @author Morten Jorgensen * @author Erwin Bolwidt <ejb@klomp.org> * @author Todd Miller */class FunctionCall extends Expression { // Name of this function call private QName _fname; // Arguments to this function call (might not be any) private final Vector _arguments; // Empty argument list, used for certain functions private final static Vector EMPTY_ARG_LIST = new Vector(0); // Valid namespaces for Java function-call extension protected final static String EXT_XSLTC = TRANSLET_URI; protected final static String JAVA_EXT_XSLTC = EXT_XSLTC + "/java"; protected final static String EXT_XALAN = "http://xml.apache.org/xalan"; protected final static String JAVA_EXT_XALAN = "http://xml.apache.org/xalan/java"; protected final static String JAVA_EXT_XALAN_OLD = "http://xml.apache.org/xslt/java"; protected final static String EXSLT_COMMON = "http://exslt.org/common"; protected final static String EXSLT_MATH = "http://exslt.org/math"; protected final static String EXSLT_SETS = "http://exslt.org/sets"; protected final static String EXSLT_DATETIME = "http://exslt.org/dates-and-times"; protected final static String EXSLT_STRINGS = "http://exslt.org/strings"; // Namespace format constants protected final static int NAMESPACE_FORMAT_JAVA = 0; protected final static int NAMESPACE_FORMAT_CLASS = 1; protected final static int NAMESPACE_FORMAT_PACKAGE = 2; protected final static int NAMESPACE_FORMAT_CLASS_OR_PACKAGE = 3; // Namespace format private int _namespace_format = NAMESPACE_FORMAT_JAVA; /** * Stores reference to object for non-static Java calls */ Expression _thisArgument = null; // External Java function's class/method/signature private String _className; private Class _clazz; private Method _chosenMethod; private Constructor _chosenConstructor; private MethodType _chosenMethodType; // Encapsulates all unsupported external function calls private boolean unresolvedExternal; // If FunctionCall is a external java constructor private boolean _isExtConstructor = false; // If the java method is static private boolean _isStatic = false; // Legal conversions between internal and Java types. private static final MultiHashtable _internal2Java = new MultiHashtable(); // Legal conversions between Java and internal types. private static final Hashtable _java2Internal = new Hashtable(); // The mappings between EXSLT extension namespaces and implementation classes private static final Hashtable _extensionNamespaceTable = new Hashtable(); // Extension functions that are implemented in BasisLibrary private static final Hashtable _extensionFunctionTable = new Hashtable(); /** * inner class to used in internal2Java mappings, contains * the Java type and the distance between the internal type and * the Java type. */ static class JavaType { public Class type; public int distance; public JavaType(Class type, int distance){ this.type = type; this.distance = distance; } public boolean equals(Object query){ return query.equals(type); } } /** * Defines 2 conversion tables: * 1. From internal types to Java types and * 2. From Java types to internal types. * These two tables are used when calling external (Java) functions. */ static { try { final Class nodeClass = Class.forName("org.w3c.dom.Node"); final Class nodeListClass = Class.forName("org.w3c.dom.NodeList"); // -- Internal to Java -------------------------------------------- // Type.Boolean -> { boolean(0), Boolean(1), Object(2) } _internal2Java.put(Type.Boolean, new JavaType(Boolean.TYPE, 0)); _internal2Java.put(Type.Boolean, new JavaType(Boolean.class, 1)); _internal2Java.put(Type.Boolean, new JavaType(Object.class, 2)); // Type.Real -> { double(0), Double(1), float(2), long(3), int(4), // short(5), byte(6), char(7), Object(8) } _internal2Java.put(Type.Real, new JavaType(Double.TYPE, 0)); _internal2Java.put(Type.Real, new JavaType(Double.class, 1)); _internal2Java.put(Type.Real, new JavaType(Float.TYPE, 2)); _internal2Java.put(Type.Real, new JavaType(Long.TYPE, 3)); _internal2Java.put(Type.Real, new JavaType(Integer.TYPE, 4)); _internal2Java.put(Type.Real, new JavaType(Short.TYPE, 5)); _internal2Java.put(Type.Real, new JavaType(Byte.TYPE, 6)); _internal2Java.put(Type.Real, new JavaType(Character.TYPE, 7)); _internal2Java.put(Type.Real, new JavaType(Object.class, 8)); // Type.Int must be the same as Type.Real _internal2Java.put(Type.Int, new JavaType(Double.TYPE, 0)); _internal2Java.put(Type.Int, new JavaType(Double.class, 1)); _internal2Java.put(Type.Int, new JavaType(Float.TYPE, 2)); _internal2Java.put(Type.Int, new JavaType(Long.TYPE, 3)); _internal2Java.put(Type.Int, new JavaType(Integer.TYPE, 4)); _internal2Java.put(Type.Int, new JavaType(Short.TYPE, 5)); _internal2Java.put(Type.Int, new JavaType(Byte.TYPE, 6)); _internal2Java.put(Type.Int, new JavaType(Character.TYPE, 7)); _internal2Java.put(Type.Int, new JavaType(Object.class, 8)); // Type.String -> { String(0), Object(1) } _internal2Java.put(Type.String, new JavaType(String.class, 0)); _internal2Java.put(Type.String, new JavaType(Object.class, 1)); // Type.NodeSet -> { NodeList(0), Node(1), Object(2), String(3) } _internal2Java.put(Type.NodeSet, new JavaType(nodeListClass, 0)); _internal2Java.put(Type.NodeSet, new JavaType(nodeClass, 1)); _internal2Java.put(Type.NodeSet, new JavaType(Object.class, 2)); _internal2Java.put(Type.NodeSet, new JavaType(String.class, 3)); // Type.Node -> { Node(0), NodeList(1), Object(2), String(3) } _internal2Java.put(Type.Node, new JavaType(nodeListClass, 0)); _internal2Java.put(Type.Node, new JavaType(nodeClass, 1)); _internal2Java.put(Type.Node, new JavaType(Object.class, 2)); _internal2Java.put(Type.Node, new JavaType(String.class, 3)); // Type.ResultTree -> { NodeList(0), Node(1), Object(2), String(3) } _internal2Java.put(Type.ResultTree, new JavaType(nodeListClass, 0)); _internal2Java.put(Type.ResultTree, new JavaType(nodeClass, 1)); _internal2Java.put(Type.ResultTree, new JavaType(Object.class, 2)); _internal2Java.put(Type.ResultTree, new JavaType(String.class, 3)); _internal2Java.put(Type.Reference, new JavaType(Object.class, 0)); // Possible conversions between Java and internal types _java2Internal.put(Boolean.TYPE, Type.Boolean); _java2Internal.put(Void.TYPE, Type.Void); _java2Internal.put(Character.TYPE, Type.Real); _java2Internal.put(Byte.TYPE, Type.Real); _java2Internal.put(Short.TYPE, Type.Real); _java2Internal.put(Integer.TYPE, Type.Real); _java2Internal.put(Long.TYPE, Type.Real); _java2Internal.put(Float.TYPE, Type.Real); _java2Internal.put(Double.TYPE, Type.Real); _java2Internal.put(String.class, Type.String); _java2Internal.put(Object.class, Type.Reference); // Conversions from org.w3c.dom.Node/NodeList to internal NodeSet _java2Internal.put(nodeListClass, Type.NodeSet); _java2Internal.put(nodeClass, Type.NodeSet); // Initialize the extension namespace table _extensionNamespaceTable.put(EXT_XALAN, "com.sun.org.apache.xalan.internal.lib.Extensions"); _extensionNamespaceTable.put(EXSLT_COMMON, "com.sun.org.apache.xalan.internal.lib.ExsltCommon"); _extensionNamespaceTable.put(EXSLT_MATH, "com.sun.org.apache.xalan.internal.lib.ExsltMath"); _extensionNamespaceTable.put(EXSLT_SETS, "com.sun.org.apache.xalan.internal.lib.ExsltSets"); _extensionNamespaceTable.put(EXSLT_DATETIME, "com.sun.org.apache.xalan.internal.lib.ExsltDatetime"); _extensionNamespaceTable.put(EXSLT_STRINGS, "com.sun.org.apache.xalan.internal.lib.ExsltStrings"); // Initialize the extension function table _extensionFunctionTable.put(EXSLT_COMMON + ":nodeSet", "nodeset"); _extensionFunctionTable.put(EXSLT_COMMON + ":objectType", "objectType"); _extensionFunctionTable.put(EXT_XALAN + ":nodeset", "nodeset"); } catch (ClassNotFoundException e) { System.err.println(e); } } public FunctionCall(QName fname, Vector arguments) { _fname = fname; _arguments = arguments; _type = null; } public FunctionCall(QName fname) { this(fname, EMPTY_ARG_LIST); } public String getName() { return(_fname.toString()); } public void setParser(Parser parser) { super.setParser(parser); if (_arguments != null) { final int n = _arguments.size(); for (int i = 0; i < n; i++) { final Expression exp = (Expression)_arguments.elementAt(i); exp.setParser(parser); exp.setParent(this); } } } public String getClassNameFromUri(String uri) { String className = (String)_extensionNamespaceTable.get(uri); if (className != null) return className; else { if (uri.startsWith(JAVA_EXT_XSLTC)) { int length = JAVA_EXT_XSLTC.length() + 1; return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING; } else if (uri.startsWith(JAVA_EXT_XALAN)) { int length = JAVA_EXT_XALAN.length() + 1; return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING; } else if (uri.startsWith(JAVA_EXT_XALAN_OLD)) { int length = JAVA_EXT_XALAN_OLD.length() + 1; return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING; } else { int index = uri.lastIndexOf('/'); return (index > 0) ? uri.substring(index+1) : uri; } } } /** * Type check a function call. Since different type conversions apply, * type checking is different for standard and external (Java) functions. */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { if (_type != null) return _type; final String namespace = _fname.getNamespace(); String local = _fname.getLocalPart(); if (isExtension()) { _fname = new QName(null, null, local); return typeCheckStandard(stable); } else if (isStandard()) { return typeCheckStandard(stable); } // Handle extension functions (they all have a namespace) else { try { _className = getClassNameFromUri(namespace); final int pos = local.lastIndexOf('.'); if (pos > 0) { _isStatic = true; if (_className != null && _className.length() > 0) { _namespace_format = NAMESPACE_FORMAT_PACKAGE; _className = _className + "." + local.substring(0, pos); } else { _namespace_format = NAMESPACE_FORMAT_JAVA; _className = local.substring(0, pos); } _fname = new QName(namespace, null, local.substring(pos + 1)); } else { if (_className != null && _className.length() > 0) { try { _clazz = ObjectFactory.findProviderClass( _className, ObjectFactory.findClassLoader(), true); _namespace_format = NAMESPACE_FORMAT_CLASS; } catch (ClassNotFoundException e) { _namespace_format = NAMESPACE_FORMAT_PACKAGE; } } else _namespace_format = NAMESPACE_FORMAT_JAVA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -