Home | History | Annotate | Download | only in jaxp
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 // $Id: JAXPExtensionsProvider.java 468655 2006-10-28 07:12:06Z minchau $
     20 
     21 package org.apache.xpath.jaxp;
     22 
     23 import javax.xml.transform.TransformerException;
     24 import javax.xml.xpath.XPathFunctionResolver;
     25 import javax.xml.xpath.XPathFunction;
     26 import javax.xml.xpath.XPathFunctionException;
     27 
     28 import org.apache.xpath.ExtensionsProvider;
     29 import org.apache.xpath.XPathContext;
     30 import org.apache.xpath.objects.XObject;
     31 import org.apache.xpath.objects.XNodeSet;
     32 import org.apache.xpath.res.XPATHErrorResources;
     33 import org.apache.xalan.res.XSLMessages;
     34 
     35 import org.apache.xpath.functions.FuncExtFunction;
     36 import java.util.Vector;
     37 import java.util.ArrayList;
     38 import javax.xml.namespace.QName;
     39 
     40 /**
     41  *
     42  * @author Ramesh Mandava ( ramesh.mandava (at) sun.com )
     43  */
     44 public class JAXPExtensionsProvider implements ExtensionsProvider {
     45 
     46     private final XPathFunctionResolver resolver;
     47     private boolean extensionInvocationDisabled = false;
     48 
     49     public JAXPExtensionsProvider(XPathFunctionResolver resolver) {
     50         this.resolver = resolver;
     51         this.extensionInvocationDisabled = false;
     52     }
     53 
     54     public JAXPExtensionsProvider(XPathFunctionResolver resolver,
     55         boolean featureSecureProcessing ) {
     56         this.resolver = resolver;
     57         this.extensionInvocationDisabled = featureSecureProcessing;
     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 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 }
    209