001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 // $Id: JAXPExtensionsProvider.java 468655 2006-10-28 07:12:06Z minchau $ 020 021 package org.apache.xpath.jaxp; 022 023 import javax.xml.transform.TransformerException; 024 import javax.xml.xpath.XPathFunctionResolver; 025 import javax.xml.xpath.XPathFunction; 026 import javax.xml.xpath.XPathFunctionException; 027 028 import org.apache.xpath.ExtensionsProvider; 029 import org.apache.xpath.XPathContext; 030 import org.apache.xpath.objects.XObject; 031 import org.apache.xpath.objects.XNodeSet; 032 import org.apache.xpath.res.XPATHErrorResources; 033 import org.apache.xalan.res.XSLMessages; 034 035 import org.apache.xpath.functions.FuncExtFunction; 036 import java.util.Vector; 037 import java.util.ArrayList; 038 import javax.xml.namespace.QName; 039 040 /** 041 * 042 * @author Ramesh Mandava ( ramesh.mandava@sun.com ) 043 */ 044 public class JAXPExtensionsProvider implements ExtensionsProvider { 045 046 private final XPathFunctionResolver resolver; 047 private boolean extensionInvocationDisabled = false; 048 049 public JAXPExtensionsProvider(XPathFunctionResolver resolver) { 050 this.resolver = resolver; 051 this.extensionInvocationDisabled = false; 052 } 053 054 public JAXPExtensionsProvider(XPathFunctionResolver resolver, 055 boolean featureSecureProcessing ) { 056 this.resolver = resolver; 057 this.extensionInvocationDisabled = featureSecureProcessing; 058 } 059 060 /** 061 * Is the extension function available? 062 */ 063 064 public boolean functionAvailable(String ns, String funcName) 065 throws javax.xml.transform.TransformerException { 066 try { 067 if ( funcName == null ) { 068 String fmsg = XSLMessages.createXPATHMessage( 069 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 070 new Object[] {"Function Name"} ); 071 throw new NullPointerException ( fmsg ); 072 } 073 //Find the XPathFunction corresponding to namespace and funcName 074 javax.xml.namespace.QName myQName = new QName( ns, funcName ); 075 javax.xml.xpath.XPathFunction xpathFunction = 076 resolver.resolveFunction ( myQName, 0 ); 077 if ( xpathFunction == null ) { 078 return false; 079 } 080 return true; 081 } catch ( Exception e ) { 082 return false; 083 } 084 085 086 } 087 088 089 /** 090 * Is the extension element available? 091 */ 092 public boolean elementAvailable(String ns, String elemName) 093 throws javax.xml.transform.TransformerException { 094 return false; 095 } 096 097 /** 098 * Execute the extension function. 099 */ 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 org.apache.xml.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 org.apache.xml.utils.WrappedRuntimeException ( xfe ); 203 } catch ( Exception e ) { 204 throw new javax.xml.transform.TransformerException ( e ); 205 } 206 } 207 208 }