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.templates;
  58. import java.util.Vector;
  59. import org.apache.xml.utils.QName;
  60. import org.apache.xml.utils.NameSpace;
  61. import org.apache.xml.utils.StringToStringTable;
  62. import org.apache.xml.utils.StringVector;
  63. import org.apache.xalan.extensions.ExtensionHandler;
  64. import org.apache.xalan.extensions.ExtensionHandlerGeneral;
  65. import org.apache.xalan.extensions.ExtensionsTable;
  66. import org.apache.xalan.transformer.TransformerImpl;
  67. import javax.xml.transform.TransformerException;
  68. import org.apache.xpath.XPathContext;
  69. import org.apache.xalan.res.XSLTErrorResources;
  70. import org.apache.xalan.res.XSLMessages;
  71. // dml
  72. import org.apache.xalan.extensions.ExtensionNamespacesManager;
  73. import org.apache.xalan.extensions.ExtensionNamespaceSupport;
  74. /**
  75. * <meta name="usage" content="internal"/>
  76. * Implement the declaration of an extension element
  77. */
  78. public class ElemExtensionDecl extends ElemTemplateElement
  79. {
  80. /**
  81. * Constructor ElemExtensionDecl
  82. *
  83. */
  84. public ElemExtensionDecl()
  85. {
  86. // System.out.println("ElemExtensionDecl ctor");
  87. }
  88. /** Prefix string for this extension element.
  89. * @serial */
  90. private String m_prefix = null;
  91. /**
  92. * Set the prefix for this extension element
  93. *
  94. *
  95. * @param v Prefix to set for this extension element
  96. */
  97. public void setPrefix(String v)
  98. {
  99. m_prefix = v;
  100. }
  101. /**
  102. * Get the prefix for this extension element
  103. *
  104. *
  105. * @return Prefix for this extension element
  106. */
  107. public String getPrefix()
  108. {
  109. return m_prefix;
  110. }
  111. /** StringVector holding the names of functions defined in this extension.
  112. * @serial */
  113. private StringVector m_functions = new StringVector();
  114. /**
  115. * Set the names of functions defined in this extension
  116. *
  117. *
  118. * @param v StringVector holding the names of functions defined in this extension
  119. */
  120. public void setFunctions(StringVector v)
  121. {
  122. m_functions = v;
  123. }
  124. /**
  125. * Get the names of functions defined in this extension
  126. *
  127. *
  128. * @return StringVector holding the names of functions defined in this extension
  129. */
  130. public StringVector getFunctions()
  131. {
  132. return m_functions;
  133. }
  134. /**
  135. * Get a function at a given index in this extension element
  136. *
  137. *
  138. * @param i Index of function to get
  139. *
  140. * @return Name of Function at given index
  141. *
  142. * @throws ArrayIndexOutOfBoundsException
  143. */
  144. public String getFunction(int i) throws ArrayIndexOutOfBoundsException
  145. {
  146. if (null == m_functions)
  147. throw new ArrayIndexOutOfBoundsException();
  148. return (String) m_functions.elementAt(i);
  149. }
  150. /**
  151. * Get count of functions defined in this extension element
  152. *
  153. *
  154. * @return count of functions defined in this extension element
  155. */
  156. public int getFunctionCount()
  157. {
  158. return (null != m_functions) ? m_functions.size() : 0;
  159. }
  160. /** StringVector of elements defined in this extension.
  161. * @serial */
  162. private StringVector m_elements = null;
  163. /**
  164. * Set StringVector of elements for this extension
  165. *
  166. *
  167. * @param v StringVector of elements to set
  168. */
  169. public void setElements(StringVector v)
  170. {
  171. m_elements = v;
  172. }
  173. /**
  174. * Get StringVector of elements defined for this extension
  175. *
  176. *
  177. * @return StringVector of elements defined for this extension
  178. */
  179. public StringVector getElements()
  180. {
  181. return m_elements;
  182. }
  183. /**
  184. * Get the element at the given index
  185. *
  186. *
  187. * @param i Index of element to get
  188. *
  189. * @return The element at the given index
  190. *
  191. * @throws ArrayIndexOutOfBoundsException
  192. */
  193. public String getElement(int i) throws ArrayIndexOutOfBoundsException
  194. {
  195. if (null == m_elements)
  196. throw new ArrayIndexOutOfBoundsException();
  197. return (String) m_elements.elementAt(i);
  198. }
  199. /**
  200. * Return the count of elements defined for this extension element
  201. *
  202. *
  203. * @return the count of elements defined for this extension element
  204. */
  205. public int getElementCount()
  206. {
  207. return (null != m_elements) ? m_elements.size() : 0;
  208. }
  209. /**
  210. * Get an int constant identifying the type of element.
  211. * @see org.apache.xalan.templates.Constants
  212. *
  213. * @return The token ID for this element
  214. */
  215. public int getXSLToken()
  216. {
  217. return Constants.ELEMNAME_EXTENSIONDECL;
  218. }
  219. public void compose(StylesheetRoot sroot) throws TransformerException
  220. {
  221. super.compose(sroot);
  222. String prefix = getPrefix();
  223. String declNamespace = getNamespaceForPrefix(prefix);
  224. String lang = null;
  225. String srcURL = null;
  226. String scriptSrc = null;
  227. if (null == declNamespace)
  228. throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[]{prefix}));
  229. //"Prefix " + prefix does not have a corresponding namespace declaration");
  230. for (ElemTemplateElement child = getFirstChildElem(); child != null;
  231. child = child.getNextSiblingElem())
  232. {
  233. if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken())
  234. {
  235. ElemExtensionScript sdecl = (ElemExtensionScript) child;
  236. lang = sdecl.getLang();
  237. srcURL = sdecl.getSrc();
  238. ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem();
  239. if (null != childOfSDecl)
  240. {
  241. if (Constants.ELEMNAME_TEXTLITERALRESULT
  242. == childOfSDecl.getXSLToken())
  243. {
  244. ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl;
  245. char[] chars = tl.getChars();
  246. scriptSrc = new String(chars);
  247. if (scriptSrc.trim().length() == 0)
  248. scriptSrc = null;
  249. }
  250. }
  251. }
  252. }
  253. if (null == lang)
  254. lang = "javaclass";
  255. if (lang.equals("javaclass") && (scriptSrc != null))
  256. throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[]{scriptSrc}));
  257. //"Element content not allowed for lang=javaclass " + scriptSrc);
  258. // Register the extension namespace if it has not already been registered.
  259. ExtensionNamespaceSupport extNsSpt = null;
  260. ExtensionNamespacesManager extNsMgr = sroot.getExtensionNamespacesManager();
  261. if (extNsMgr.namespaceIndex(declNamespace,
  262. extNsMgr.getExtensions()) == -1)
  263. {
  264. if (lang.equals("javaclass"))
  265. {
  266. if (null == srcURL)
  267. {
  268. extNsSpt = extNsMgr.defineJavaNamespace(declNamespace);
  269. }
  270. else if (extNsMgr.namespaceIndex(srcURL,
  271. extNsMgr.getExtensions()) == -1)
  272. {
  273. extNsSpt = extNsMgr.defineJavaNamespace(declNamespace, srcURL);
  274. }
  275. }
  276. else // not java
  277. {
  278. String handler = "org.apache.xalan.extensions.ExtensionHandlerGeneral";
  279. Object [] args = {declNamespace, this.m_elements, this.m_functions,
  280. lang, srcURL, scriptSrc, getSystemId()};
  281. extNsSpt = new ExtensionNamespaceSupport(declNamespace, handler, args);
  282. }
  283. }
  284. if (extNsSpt != null)
  285. extNsMgr.registerExtension(extNsSpt);
  286. }
  287. /**
  288. * This function will be called on top-level elements
  289. * only, just before the transform begins.
  290. *
  291. * @param transformer The XSLT TransformerFactory.
  292. *
  293. * @throws TransformerException
  294. */
  295. public void runtimeInit(TransformerImpl transformer) throws TransformerException
  296. {
  297. /* //System.out.println("ElemExtensionDecl.runtimeInit()");
  298. String lang = null;
  299. String srcURL = null;
  300. String scriptSrc = null;
  301. String prefix = getPrefix();
  302. String declNamespace = getNamespaceForPrefix(prefix);
  303. if (null == declNamespace)
  304. throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[]{prefix}));
  305. //"Prefix " + prefix does not have a corresponding namespace declaration");
  306. for (ElemTemplateElement child = getFirstChildElem(); child != null;
  307. child = child.getNextSiblingElem())
  308. {
  309. if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken())
  310. {
  311. ElemExtensionScript sdecl = (ElemExtensionScript) child;
  312. lang = sdecl.getLang();
  313. srcURL = sdecl.getSrc();
  314. ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem();
  315. if (null != childOfSDecl)
  316. {
  317. if (Constants.ELEMNAME_TEXTLITERALRESULT
  318. == childOfSDecl.getXSLToken())
  319. {
  320. ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl;
  321. char[] chars = tl.getChars();
  322. scriptSrc = new String(chars);
  323. if (scriptSrc.trim().length() == 0)
  324. scriptSrc = null;
  325. }
  326. }
  327. }
  328. }
  329. if (null == lang)
  330. lang = "javaclass";
  331. if (lang.equals("javaclass") && (scriptSrc != null))
  332. throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[]{scriptSrc}));
  333. //"Element content not allowed for lang=javaclass " + scriptSrc);
  334. // Instantiate a handler for this extension namespace.
  335. ExtensionsTable etable = transformer.getExtensionsTable();
  336. ExtensionHandler nsh = etable.get(declNamespace);
  337. // If we have no prior ExtensionHandler for this namespace, we need to
  338. // create one.
  339. // If the script element is for javaclass, this is our special compiled java.
  340. // Element content is not supported for this so we throw an exception if
  341. // it is provided. Otherwise, we look up the srcURL to see if we already have
  342. // an ExtensionHandler.
  343. if (null == nsh)
  344. {
  345. if (lang.equals("javaclass"))
  346. {
  347. if (null == srcURL)
  348. {
  349. nsh = etable.makeJavaNamespace(declNamespace);
  350. }
  351. else
  352. {
  353. nsh = etable.get(srcURL);
  354. if (null == nsh)
  355. {
  356. nsh = etable.makeJavaNamespace(srcURL);
  357. }
  358. }
  359. }
  360. else // not java
  361. {
  362. nsh = new ExtensionHandlerGeneral(declNamespace, this.m_elements,
  363. this.m_functions, lang, srcURL,
  364. scriptSrc, getSystemId());
  365. // System.out.println("Adding NS Handler: declNamespace = "+
  366. // declNamespace+", lang = "+lang+", srcURL = "+
  367. // srcURL+", scriptSrc="+scriptSrc);
  368. }
  369. etable.addExtensionNamespace(declNamespace, nsh);
  370. }*/
  371. }
  372. }