1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.extensions;
  58. import java.util.Vector;
  59. import java.lang.reflect.Method;
  60. import java.lang.reflect.Modifier;
  61. import java.lang.reflect.Constructor;
  62. import java.lang.reflect.InvocationTargetException;
  63. import java.io.IOException;
  64. import org.w3c.dom.NodeList;
  65. import org.w3c.dom.Node;
  66. import org.apache.xalan.transformer.TransformerImpl;
  67. import org.apache.xalan.templates.ElemTemplateElement;
  68. import org.apache.xalan.templates.Stylesheet;
  69. import org.apache.xalan.templates.StylesheetRoot;
  70. import org.apache.xalan.templates.ElemTemplate;
  71. import org.apache.xalan.templates.ElemExsltFunction;
  72. import org.apache.xalan.templates.ElemExsltFuncResult;
  73. import org.apache.xalan.templates.Constants;
  74. import org.apache.xml.utils.QName;
  75. import org.apache.xpath.XPathContext;
  76. import org.apache.xpath.VariableStack;
  77. import org.apache.xpath.objects.XObject;
  78. import org.apache.xpath.objects.XString;
  79. import javax.xml.transform.TransformerException;
  80. /**
  81. * Execute EXSLT functions, determine the availability of EXSLT functions, and the
  82. * availability of an EXSLT result element.
  83. */
  84. public class ExtensionHandlerExsltFunction extends ExtensionHandler
  85. {
  86. private String m_namespace;
  87. private StylesheetRoot m_stylesheet;
  88. private static final QName RESULTQNAME =
  89. new QName(Constants.S_EXSLT_FUNCTIONS_URL,
  90. Constants.EXSLT_ELEMNAME_FUNCRESULT_STRING);
  91. /**
  92. * Constructor called from ElemExsltFunction runtimeInit().
  93. */
  94. public ExtensionHandlerExsltFunction(String ns, StylesheetRoot stylesheet)
  95. {
  96. super(ns, "xml"); // required by ExtensionHandler interface.
  97. m_namespace = ns;
  98. m_stylesheet = stylesheet;
  99. }
  100. /**
  101. * Required by ExtensionHandler (an abstract method). No-op.
  102. */
  103. public void processElement(
  104. String localPart, ElemTemplateElement element, TransformerImpl transformer,
  105. Stylesheet stylesheetTree, Object methodKey) throws TransformerException, IOException
  106. {}
  107. /**
  108. * Get the ElemExsltFunction element associated with the
  109. * function.
  110. *
  111. * @param funcName Local name of the function.
  112. * @return the ElemExsltFunction element associated with
  113. * the function, null if none exists.
  114. */
  115. public ElemExsltFunction getFunction(String funcName)
  116. {
  117. QName qname = new QName(m_namespace, funcName);
  118. ElemTemplate templ = m_stylesheet.getTemplateComposed(qname);
  119. if (templ != null && templ instanceof ElemExsltFunction)
  120. return (ElemExsltFunction) templ;
  121. else
  122. return null;
  123. }
  124. /**
  125. * Does the EXSLT function exist?
  126. *
  127. * @param funcName Local name of the function.
  128. * @return true if the function exists.
  129. */
  130. public boolean isFunctionAvailable(String funcName)
  131. {
  132. return getFunction(funcName)!= null;
  133. }
  134. /** If an element-available() call applies to an EXSLT result element within
  135. * an EXSLT function element, return true.
  136. *
  137. * Note: The EXSLT function element is a template-level element, and
  138. * element-available() returns false for it.
  139. *
  140. * @param Local name of the function.
  141. * @return true if the function is available.
  142. */
  143. public boolean isElementAvailable(String elemName)
  144. {
  145. if (!(new QName(m_namespace, elemName).equals(RESULTQNAME)))
  146. {
  147. return false;
  148. }
  149. else
  150. {
  151. ElemTemplateElement elem = m_stylesheet.getFirstChildElem();
  152. while (elem != null && elem != m_stylesheet)
  153. {
  154. if (elem instanceof ElemExsltFuncResult && ancestorIsFunction(elem))
  155. return true;
  156. ElemTemplateElement nextElem = elem.getFirstChildElem();
  157. if (nextElem == null)
  158. nextElem = elem.getNextSiblingElem();
  159. if (nextElem == null)
  160. nextElem = elem.getParentElem();
  161. elem = nextElem;
  162. }
  163. }
  164. return false;
  165. }
  166. /**
  167. * Determine whether the func:result element is within a func:function element.
  168. * If not, it is illegal.
  169. */
  170. private boolean ancestorIsFunction(ElemTemplateElement child)
  171. {
  172. while (child.getParentElem() != null
  173. && !(child.getParentElem() instanceof StylesheetRoot))
  174. {
  175. if (child.getParentElem() instanceof ElemExsltFunction)
  176. return true;
  177. child = child.getParentElem();
  178. }
  179. return false;
  180. }
  181. /**
  182. * Execute the EXSLT function and return the result value.
  183. *
  184. * @param funcName Name of the EXSLT function.
  185. * @param args The arguments of the function call.
  186. * @param methodKey Not used.
  187. * @param exprContext Used to get the XPathContext.
  188. * @return the return value of the function evaluation.
  189. * @throws TransformerException
  190. */
  191. public Object callFunction(
  192. String funcName, Vector args, Object methodKey,
  193. ExpressionContext exprContext) throws TransformerException
  194. {
  195. XObject[] methodArgs;
  196. methodArgs = new XObject[args.size()];
  197. try
  198. {
  199. for (int i = 0; i < methodArgs.length; i++)
  200. {
  201. methodArgs[i] = XObject.create(args.elementAt(i));
  202. }
  203. ElemExsltFunction elemFunc = getFunction(funcName);
  204. XPathContext context = exprContext.getXPathContext();
  205. TransformerImpl transformer = (TransformerImpl)context.getOwnerObject();
  206. elemFunc.execute(transformer, methodArgs);
  207. VariableStack varStack = context.getVarStack();
  208. XObject val = new XString(""); // value returned if no result element.
  209. int resultIndex = elemFunc.getResultIndex();
  210. if (varStack.isLocalSet(resultIndex))
  211. val = varStack.getLocalVariable(context, resultIndex);
  212. return val;
  213. }
  214. catch (Exception e)
  215. {
  216. // e.printStackTrace();
  217. throw new TransformerException(e);
  218. }
  219. }
  220. }