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: ExtensionsTable.java 469672 2006-10-31 21:56:19Z minchau $ 20 */ 21 package org.apache.xalan.extensions; 22 23 import java.util.Hashtable; 24 import java.util.Vector; 25 26 import org.apache.xalan.res.XSLMessages; 27 import org.apache.xalan.res.XSLTErrorResources; 28 import org.apache.xalan.templates.StylesheetRoot; 29 import org.apache.xpath.XPathProcessorException; 30 import org.apache.xpath.functions.FuncExtFunction; 31 32 /** 33 * Class holding a table registered extension namespace handlers 34 * @xsl.usage internal 35 */ 36 public class ExtensionsTable 37 { 38 /** 39 * Table of extensions that may be called from the expression language 40 * via the call(name, ...) function. Objects are keyed on the call 41 * name. 42 * @xsl.usage internal 43 */ 44 public Hashtable m_extensionFunctionNamespaces = new Hashtable(); 45 46 /** 47 * The StylesheetRoot associated with this extensions table. 48 */ 49 private StylesheetRoot m_sroot; 50 51 /** 52 * The constructor (called from TransformerImpl) registers the 53 * StylesheetRoot for the transformation and instantiates an 54 * ExtensionHandler for each extension namespace. 55 * @xsl.usage advanced 56 */ 57 public ExtensionsTable(StylesheetRoot sroot) 58 throws javax.xml.transform.TransformerException 59 { 60 m_sroot = sroot; 61 Vector extensions = m_sroot.getExtensions(); 62 for (int i = 0; i < extensions.size(); i++) 63 { 64 ExtensionNamespaceSupport extNamespaceSpt = 65 (ExtensionNamespaceSupport)extensions.get(i); 66 ExtensionHandler extHandler = extNamespaceSpt.launch(); 67 if (extHandler != null) 68 addExtensionNamespace(extNamespaceSpt.getNamespace(), extHandler); 69 } 70 } 71 72 /** 73 * Get an ExtensionHandler object that represents the 74 * given namespace. 75 * @param extns A valid extension namespace. 76 * 77 * @return ExtensionHandler object that represents the 78 * given namespace. 79 */ 80 public ExtensionHandler get(String extns) 81 { 82 return (ExtensionHandler) m_extensionFunctionNamespaces.get(extns); 83 } 84 85 /** 86 * Register an extension namespace handler. This handler provides 87 * functions for testing whether a function is known within the 88 * namespace and also for invoking the functions. 89 * 90 * @param uri the URI for the extension. 91 * @param extNS the extension handler. 92 * @xsl.usage advanced 93 */ 94 public void addExtensionNamespace(String uri, ExtensionHandler extNS) 95 { 96 m_extensionFunctionNamespaces.put(uri, extNS); 97 } 98 99 /** 100 * Execute the function-available() function. 101 * @param ns the URI of namespace in which the function is needed 102 * @param funcName the function name being tested 103 * 104 * @return whether the given function is available or not. 105 * 106 * @throws javax.xml.transform.TransformerException 107 */ 108 public boolean functionAvailable(String ns, String funcName) 109 throws javax.xml.transform.TransformerException 110 { 111 boolean isAvailable = false; 112 113 if (null != ns) 114 { 115 ExtensionHandler extNS = 116 (ExtensionHandler) m_extensionFunctionNamespaces.get(ns); 117 if (extNS != null) 118 isAvailable = extNS.isFunctionAvailable(funcName); 119 } 120 return isAvailable; 121 } 122 123 /** 124 * Execute the element-available() function. 125 * @param ns the URI of namespace in which the function is needed 126 * @param elemName name of element being tested 127 * 128 * @return whether the given element is available or not. 129 * 130 * @throws javax.xml.transform.TransformerException 131 */ 132 public boolean elementAvailable(String ns, String elemName) 133 throws javax.xml.transform.TransformerException 134 { 135 boolean isAvailable = false; 136 if (null != ns) 137 { 138 ExtensionHandler extNS = 139 (ExtensionHandler) m_extensionFunctionNamespaces.get(ns); 140 if (extNS != null) // defensive 141 isAvailable = extNS.isElementAvailable(elemName); 142 } 143 return isAvailable; 144 } 145 146 /** 147 * Handle an extension function. 148 * @param ns the URI of namespace in which the function is needed 149 * @param funcName the function name being called 150 * @param argVec arguments to the function in a vector 151 * @param methodKey a unique key identifying this function instance in the 152 * stylesheet 153 * @param exprContext a context which may be passed to an extension function 154 * and provides callback functions to access various 155 * areas in the environment 156 * 157 * @return result of executing the function 158 * 159 * @throws javax.xml.transform.TransformerException 160 */ 161 public Object extFunction(String ns, String funcName, 162 Vector argVec, Object methodKey, 163 ExpressionContext exprContext) 164 throws javax.xml.transform.TransformerException 165 { 166 Object result = null; 167 if (null != ns) 168 { 169 ExtensionHandler extNS = 170 (ExtensionHandler) m_extensionFunctionNamespaces.get(ns); 171 if (null != extNS) 172 { 173 try 174 { 175 result = extNS.callFunction(funcName, argVec, methodKey, 176 exprContext); 177 } 178 catch (javax.xml.transform.TransformerException e) 179 { 180 throw e; 181 } 182 catch (Exception e) 183 { 184 throw new javax.xml.transform.TransformerException(e); 185 } 186 } 187 else 188 { 189 throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, new Object[]{ns, funcName })); 190 //"Extension function '" + ns + ":" + funcName + "' is unknown"); 191 } 192 } 193 return result; 194 } 195 196 /** 197 * Handle an extension function. 198 * @param extFunction the extension function 199 * @param argVec arguments to the function in a vector 200 * @param exprContext a context which may be passed to an extension function 201 * and provides callback functions to access various 202 * areas in the environment 203 * 204 * @return result of executing the function 205 * 206 * @throws javax.xml.transform.TransformerException 207 */ 208 public Object extFunction(FuncExtFunction extFunction, Vector argVec, 209 ExpressionContext exprContext) 210 throws javax.xml.transform.TransformerException 211 { 212 Object result = null; 213 String ns = extFunction.getNamespace(); 214 if (null != ns) 215 { 216 ExtensionHandler extNS = 217 (ExtensionHandler) m_extensionFunctionNamespaces.get(ns); 218 if (null != extNS) 219 { 220 try 221 { 222 result = extNS.callFunction(extFunction, argVec, exprContext); 223 } 224 catch (javax.xml.transform.TransformerException e) 225 { 226 throw e; 227 } 228 catch (Exception e) 229 { 230 throw new javax.xml.transform.TransformerException(e); 231 } 232 } 233 else 234 { 235 throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, 236 new Object[]{ns, extFunction.getFunctionName()})); 237 } 238 } 239 return result; 240 } 241 } 242