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