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