1 /* 2 * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 3 * @LastModified: Nov 2017 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.xpath.internal.jaxp; 23 24 import com.sun.org.apache.xalan.internal.res.XSLMessages; 25 import com.sun.org.apache.xpath.internal.ExtensionsProvider; 26 import com.sun.org.apache.xpath.internal.functions.FuncExtFunction; 27 import com.sun.org.apache.xpath.internal.objects.XNodeSet; 28 import com.sun.org.apache.xpath.internal.objects.XObject; 29 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; 30 import java.util.ArrayList; 31 import java.util.List; 32 import javax.xml.namespace.QName; 33 import javax.xml.xpath.XPathFunction; 34 import javax.xml.xpath.XPathFunctionException; 35 import javax.xml.xpath.XPathFunctionResolver; 36 import jdk.xml.internal.JdkXmlFeatures; 37 38 /** 39 * 40 * @author Ramesh Mandava ( ramesh.mandava@sun.com ) 41 */ 42 public class JAXPExtensionsProvider implements ExtensionsProvider { 43 44 private final XPathFunctionResolver resolver; 45 private boolean extensionInvocationDisabled = false; 46 47 public JAXPExtensionsProvider(XPathFunctionResolver resolver) { 48 this.resolver = resolver; 49 this.extensionInvocationDisabled = false; 50 } 51 52 public JAXPExtensionsProvider(XPathFunctionResolver resolver, 53 boolean featureSecureProcessing, JdkXmlFeatures featureManager ) { 54 this.resolver = resolver; 55 if (featureSecureProcessing && 56 !featureManager.getFeature(JdkXmlFeatures.XmlFeature.ENABLE_EXTENSION_FUNCTION)) { 57 this.extensionInvocationDisabled = true; 58 } 59 } 60 61 /** 62 * Is the extension function available? 63 */ 64 65 public boolean functionAvailable(String ns, String funcName) 66 throws javax.xml.transform.TransformerException { 67 try { 68 if ( funcName == null ) { 69 String fmsg = XSLMessages.createXPATHMessage( 70 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 71 new Object[] {"Function Name"} ); 72 throw new NullPointerException ( fmsg ); 73 } 74 //Find the XPathFunction corresponding to namespace and funcName 75 javax.xml.namespace.QName myQName = new QName( ns, funcName ); 76 javax.xml.xpath.XPathFunction xpathFunction = 77 resolver.resolveFunction ( myQName, 0 ); 78 if ( xpathFunction == null ) { 79 return false; 80 } 81 return true; 82 } catch ( Exception e ) { 83 return false; 84 } 85 86 87 } 88 89 90 /** 91 * Is the extension element available? 92 */ 93 public boolean elementAvailable(String ns, String elemName) 94 throws javax.xml.transform.TransformerException { 95 return false; 96 } 97 98 /** 99 * Execute the extension function. 100 */ 101 public Object extFunction(String ns, String funcName, List<XObject> argVec, 102 Object methodKey) throws javax.xml.transform.TransformerException { 103 try { 104 105 if ( funcName == null ) { 106 String fmsg = XSLMessages.createXPATHMessage( 107 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 108 new Object[] {"Function Name"} ); 109 throw new NullPointerException ( fmsg ); 110 } 111 //Find the XPathFunction corresponding to namespace and funcName 112 javax.xml.namespace.QName myQName = new QName( ns, funcName ); 113 114 // JAXP 1.3 spec says When XMLConstants.FEATURE_SECURE_PROCESSING 115 // feature is set then invocation of extension functions need to 116 // throw XPathFunctionException 117 if ( extensionInvocationDisabled ) { 118 String fmsg = XSLMessages.createXPATHMessage( 119 XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED, 120 new Object[] { myQName.toString() } ); 121 throw new XPathFunctionException ( fmsg ); 122 } 123 124 // Assuming user is passing all the needed parameters ( including 125 // default values ) 126 int arity = argVec.size(); 127 128 javax.xml.xpath.XPathFunction xpathFunction = 129 resolver.resolveFunction ( myQName, arity ); 130 131 // not using methodKey 132 List<Object> argList = new ArrayList<>( arity); 133 for ( int i=0; i<arity; i++ ) { 134 XObject argument = argVec.get( i ); 135 // XNodeSet object() returns NodeVector and not NodeList 136 // Explicitly getting NodeList by using nodelist() 137 if ( argument instanceof XNodeSet ) { 138 argList.add ( i, ((XNodeSet)argument).nodelist() ); 139 } else if ( argument instanceof XObject ) { 140 Object passedArgument = argument.object(); 141 argList.add ( i, passedArgument ); 142 } else { 143 argList.add ( i, argument ); 144 } 145 } 146 147 return ( xpathFunction.evaluate ( argList )); 148 } catch ( XPathFunctionException xfe ) { 149 // If we get XPathFunctionException then we want to terminate 150 // further execution by throwing WrappedRuntimeException 151 throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException ( xfe ); 152 } catch ( Exception e ) { 153 throw new javax.xml.transform.TransformerException ( e ); 154 } 155 156 } 157 158 /** 159 * Execute the extension function. 160 */ 161 public Object extFunction(FuncExtFunction extFunction, List<XObject> argVec) 162 throws javax.xml.transform.TransformerException { 163 try { 164 String namespace = extFunction.getNamespace(); 165 String functionName = extFunction.getFunctionName(); 166 int arity = extFunction.getArgCount(); 167 javax.xml.namespace.QName myQName = 168 new javax.xml.namespace.QName( namespace, functionName ); 169 170 // JAXP 1.3 spec says When XMLConstants.FEATURE_SECURE_PROCESSING 171 // feature is set then invocation of extension functions need to 172 // throw XPathFunctionException 173 if ( extensionInvocationDisabled ) { 174 String fmsg = XSLMessages.createXPATHMessage( 175 XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED, 176 new Object[] { myQName.toString() } ); 177 throw new XPathFunctionException ( fmsg ); 178 } 179 180 XPathFunction xpathFunction = 181 resolver.resolveFunction( myQName, arity ); 182 183 List<Object> argList = new ArrayList<>( arity); 184 for ( int i=0; i<arity; i++ ) { 185 XObject argument = argVec.get( i ); 186 // XNodeSet object() returns NodeVector and not NodeList 187 // Explicitly getting NodeList by using nodelist() 188 if ( argument instanceof XNodeSet ) { 189 argList.add ( i, ((XNodeSet)argument).nodelist() ); 190 } else if ( argument instanceof XObject ) { 191 Object passedArgument = argument.object(); 192 argList.add ( i, passedArgument ); 193 } else { 194 argList.add ( i, argument ); 195 } 196 } 197 198 return ( xpathFunction.evaluate ( argList )); 199 200 } catch ( XPathFunctionException xfe ) { 201 // If we get XPathFunctionException then we want to terminate 202 // further execution by throwing WrappedRuntimeException 203 throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException ( xfe ); 204 } catch ( Exception e ) { 205 throw new javax.xml.transform.TransformerException ( e ); 206 } 207 } 208 209 }