aboutsummaryrefslogtreecommitdiff
path: root/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java')
-rw-r--r--src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java282
1 files changed, 160 insertions, 122 deletions
diff --git a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
index 56bebd8..11b3241 100644
--- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
+++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
@@ -1,15 +1,15 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
*
- * 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
+ * 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,
@@ -23,13 +23,6 @@
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;
@@ -43,6 +36,7 @@ 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.utils.FeatureManager;
+import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
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;
@@ -54,8 +48,15 @@ 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;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
+import java.util.Vector;
/**
* @author Jacek Ambroziak
@@ -104,6 +105,9 @@ class FunctionCall extends Expression {
protected final static String EXSLT_STRINGS =
"http://exslt.org/strings";
+ protected final static String XALAN_CLASSPACKAGE_NAMESPACE =
+ "xalan://";
+
// Namespace format constants
protected final static int NAMESPACE_FORMAT_JAVA = 0;
protected final static int NAMESPACE_FORMAT_CLASS = 1;
@@ -135,23 +139,23 @@ class FunctionCall extends Expression {
private boolean _isStatic = false;
// Legal conversions between internal and Java types.
- private static final MultiHashtable _internal2Java = new MultiHashtable();
+ private static final MultiHashtable<Type, JavaType> _internal2Java = new MultiHashtable<>();
// Legal conversions between Java and internal types.
- private static final Hashtable _java2Internal = new Hashtable();
+ private static final Map<Class<?>, Type> JAVA2INTERNAL;
// The mappings between EXSLT extension namespaces and implementation classes
- private static final Hashtable _extensionNamespaceTable = new Hashtable();
+ private static final Map<String, String> EXTENSIONNAMESPACE;
// Extension functions that are implemented in BasisLibrary
- private static final Hashtable _extensionFunctionTable = new Hashtable();
+ private static final Map<String, String> EXTENSIONFUNCTION;
/**
* 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 Class<?> type;
public int distance;
public JavaType(Class type, int distance){
@@ -165,8 +169,15 @@ class FunctionCall extends Expression {
}
@Override
- public boolean equals(Object query){
- return query != null && query.equals(type);
+ public boolean equals(Object query) {
+ if (query == null) {
+ return false;
+ }
+ if (query.getClass().isAssignableFrom(JavaType.class)) {
+ return ((JavaType)query).type.equals(type);
+ } else {
+ return query.equals(type);
+ }
}
}
@@ -177,99 +188,112 @@ class FunctionCall extends Expression {
* These two tables are used when calling external (Java) functions.
*/
static {
+ final Class<?> nodeClass, nodeListClass;
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");
+ nodeClass = Class.forName("org.w3c.dom.Node");
+ nodeListClass = Class.forName("org.w3c.dom.NodeList");
}
catch (ClassNotFoundException e) {
- System.err.println(e);
+ ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR,"org.w3c.dom.Node or NodeList");
+ throw new ExceptionInInitializerError(err.toString());
}
+
+ // -- 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));
+
+ _internal2Java.makeUnmodifiable();
+
+ Map<Class<?>, Type> java2Internal = new HashMap<>();
+ Map<String, String> extensionNamespaceTable = new HashMap<>();
+ Map<String, String> extensionFunctionTable = new HashMap<>();
+
+ // 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");
+
+ JAVA2INTERNAL = Collections.unmodifiableMap(java2Internal);
+ EXTENSIONNAMESPACE = Collections.unmodifiableMap(extensionNamespaceTable);
+ EXTENSIONFUNCTION = Collections.unmodifiableMap(extensionFunctionTable);
+
}
public FunctionCall(QName fname, Vector arguments) {
@@ -301,7 +325,7 @@ class FunctionCall extends Expression {
public String getClassNameFromUri(String uri)
{
- String className = (String)_extensionNamespaceTable.get(uri);
+ String className = EXTENSIONNAMESPACE.get(uri);
if (className != null)
return className;
@@ -381,7 +405,7 @@ class FunctionCall extends Expression {
local = replaceDash(local);
}
- String extFunction = (String)_extensionFunctionTable.get(namespace + ":" + local);
+ String extFunction = EXTENSIONFUNCTION.get(namespace + ":" + local);
if (extFunction != null) {
_fname = new QName(null, null, extFunction);
return typeCheckStandard(stable);
@@ -461,15 +485,15 @@ class FunctionCall extends Expression {
(Constructor)constructors.elementAt(i);
final Class[] paramTypes = constructor.getParameterTypes();
- Class extType = null;
+ Class<?> extType;
int currConstrDistance = 0;
for (j = 0; j < nArgs; j++) {
// Convert from internal (translet) type to external (Java) type
extType = paramTypes[j];
final Type intType = (Type)argsType.elementAt(j);
- Object match = _internal2Java.maps(intType, extType);
+ JavaType match = _internal2Java.maps(intType, new JavaType(extType, 0));
if (match != null) {
- currConstrDistance += ((JavaType)match).distance;
+ currConstrDistance += match.distance;
}
else if (intType instanceof ObjectType) {
ObjectType objectType = (ObjectType)intType;
@@ -594,9 +618,9 @@ class FunctionCall extends Expression {
// Convert from internal (translet) type to external (Java) type
extType = paramTypes[j];
final Type intType = (Type)argsType.elementAt(j);
- Object match = _internal2Java.maps(intType, extType);
+ JavaType match = _internal2Java.maps(intType, new JavaType(extType, 0));
if (match != null) {
- currMethodDistance += ((JavaType)match).distance;
+ currMethodDistance += match.distance;
}
else {
// no mapping available
@@ -628,7 +652,7 @@ class FunctionCall extends Expression {
// Check if the return type can be converted
extType = method.getReturnType();
- _type = (Type) _java2Internal.get(extType);
+ _type = JAVA2INTERNAL.get(extType);
if (_type == null) {
_type = Type.newObjectType(extType);
}
@@ -900,8 +924,22 @@ class FunctionCall extends Expression {
if (_className != null && _className.length() > 0) {
final int nArgs = _arguments.size();
try {
- if (_clazz == null) {
- _clazz = ObjectFactory.findProviderClass(_className, true);
+ if (_clazz == null) {
+ final boolean isSecureProcessing = getXSLTC().isSecureProcessing();
+ final boolean isExtensionFunctionEnabled = getXSLTC()
+ .getFeature(FeatureManager.Feature.ORACLE_ENABLE_EXTENSION_FUNCTION);
+
+ //Check if FSP and SM - only then proceed with loading
+ if (namespace != null && isSecureProcessing
+ && isExtensionFunctionEnabled
+ && (namespace.startsWith(JAVA_EXT_XALAN)
+ || namespace.startsWith(JAVA_EXT_XSLTC)
+ || namespace.startsWith(JAVA_EXT_XALAN_OLD)
+ || namespace.startsWith(XALAN_CLASSPACKAGE_NAMESPACE))) {
+ _clazz = getXSLTC().loadExternalFunction(_className);
+ } else {
+ _clazz = ObjectFactory.findProviderClass(_className, true);
+ }
if (_clazz == null) {
final ErrorMsg msg =