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 }