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 org.apache.xalan.templates.Constants;
  59. import java.util.Vector;
  60. /**
  61. * Used during assembly of a stylesheet to collect the information for each
  62. * extension namespace that is required during the transformation process
  63. * to generate an {@link ExtensionHandler}.
  64. *
  65. */
  66. public class ExtensionNamespacesManager
  67. {
  68. /**
  69. * Vector of ExtensionNamespaceSupport objects to be used to generate ExtensionHandlers.
  70. */
  71. private Vector m_extensions = new Vector();
  72. /**
  73. * Vector of ExtensionNamespaceSupport objects for predefined ExtensionNamespaces. Elements
  74. * from this vector are added to the m_extensions vector when encountered in the stylesheet.
  75. */
  76. private Vector m_predefExtensions = new Vector(7);
  77. /**
  78. * Vector of extension namespaces for which sufficient information is not yet available to
  79. * complete the registration process.
  80. */
  81. private Vector m_unregisteredExtensions = new Vector();
  82. /**
  83. * An ExtensionNamespacesManager is instantiated the first time an extension function or
  84. * element is found in the stylesheet. During initialization, a vector of ExtensionNamespaceSupport
  85. * objects is created, one for each predefined extension namespace.
  86. */
  87. public ExtensionNamespacesManager()
  88. {
  89. setPredefinedNamespaces();
  90. }
  91. /**
  92. * If necessary, register the extension namespace found compiling a function or
  93. * creating an extension element.
  94. *
  95. * If it is a predefined namespace, create a
  96. * support object to simplify the instantiate of an appropriate ExtensionHandler
  97. * during transformation runtime. Otherwise, add the namespace, if necessary,
  98. * to a vector of undefined extension namespaces, to be defined later.
  99. *
  100. */
  101. public void registerExtension(String namespace)
  102. {
  103. if (namespaceIndex(namespace, m_extensions) == -1)
  104. {
  105. int predef = namespaceIndex(namespace, m_predefExtensions);
  106. if (predef !=-1)
  107. m_extensions.addElement(m_predefExtensions.elementAt(predef));
  108. else if (!(m_unregisteredExtensions.contains(namespace)))
  109. m_unregisteredExtensions.addElement(namespace);
  110. }
  111. }
  112. /**
  113. * Register the extension namespace for an ElemExtensionDecl or ElemFunction,
  114. * and prepare a support object to launch the appropriate ExtensionHandler at
  115. * transformation runtime.
  116. */
  117. public void registerExtension(ExtensionNamespaceSupport extNsSpt)
  118. {
  119. String namespace = extNsSpt.getNamespace();
  120. if (namespaceIndex(namespace, m_extensions) == -1)
  121. {
  122. m_extensions.addElement(extNsSpt);
  123. if (m_unregisteredExtensions.contains(namespace))
  124. m_unregisteredExtensions.removeElement(namespace);
  125. }
  126. }
  127. /**
  128. * Get the index for a namespace entry in the extension namespace Vector, -1 if
  129. * no such entry yet exists.
  130. */
  131. public int namespaceIndex(String namespace, Vector extensions)
  132. {
  133. for (int i = 0; i < extensions.size(); i++)
  134. {
  135. if (((ExtensionNamespaceSupport)extensions.elementAt(i)).getNamespace().equals(namespace))
  136. return i;
  137. }
  138. return -1;
  139. }
  140. /**
  141. * Get the vector of extension namespaces. Used to provide
  142. * the extensions table access to a list of extension
  143. * namespaces encountered during composition of a stylesheet.
  144. */
  145. public Vector getExtensions()
  146. {
  147. return m_extensions;
  148. }
  149. /**
  150. * Attempt to register any unregistered extension namespaces.
  151. */
  152. public void registerUnregisteredNamespaces()
  153. {
  154. for (int i = 0; i < m_unregisteredExtensions.size(); i++)
  155. {
  156. String ns = (String)m_unregisteredExtensions.elementAt(i);
  157. ExtensionNamespaceSupport extNsSpt = defineJavaNamespace(ns);
  158. if (extNsSpt != null)
  159. m_extensions.addElement(extNsSpt);
  160. }
  161. }
  162. /**
  163. * For any extension namespace that is not either predefined or defined
  164. * by a "component" declaration or exslt function declaration, attempt
  165. * to create an ExtensionNamespaceSuport object for the appropriate
  166. * Java class or Java package Extension Handler.
  167. *
  168. * Called by StylesheetRoot.recompose(), after all ElemTemplate compose()
  169. * operations have taken place, in order to set up handlers for
  170. * the remaining extension namespaces.
  171. *
  172. * @param ns The extension namespace URI.
  173. * @return An ExtensionNamespaceSupport object for this namespace
  174. * (which defines the ExtensionHandler to be used), or null if such
  175. * an object cannot be created.
  176. *
  177. * @throws javax.xml.transform.TransformerException
  178. */
  179. public ExtensionNamespaceSupport defineJavaNamespace(String ns)
  180. {
  181. return defineJavaNamespace(ns, ns);
  182. }
  183. public ExtensionNamespaceSupport defineJavaNamespace(String ns, String classOrPackage)
  184. {
  185. if(null == ns || ns.trim().length() == 0) // defensive. I don't think it's needed. -sb
  186. return null;
  187. // Prepare the name of the actual class or package, stripping
  188. // out any leading "class:". Next, see if there is a /. If so,
  189. // only look at the text to the right of the rightmost /.
  190. String className = classOrPackage;
  191. if (className.startsWith("class:"))
  192. className = className.substring(6);
  193. int lastSlash = className.lastIndexOf("/");
  194. if (-1 != lastSlash)
  195. className = className.substring(lastSlash + 1);
  196. // The className can be null here, and can cause an error in getClassForName
  197. // in JDK 1.8.
  198. if(null == className || className.trim().length() == 0)
  199. return null;
  200. try
  201. {
  202. ExtensionHandler.getClassForName(className);
  203. return new ExtensionNamespaceSupport(
  204. ns,
  205. "org.apache.xalan.extensions.ExtensionHandlerJavaClass",
  206. new Object[]{ns, "javaclass", className});
  207. }
  208. catch (ClassNotFoundException e)
  209. {
  210. return new ExtensionNamespaceSupport(
  211. ns,
  212. "org.apache.xalan.extensions.ExtensionHandlerJavaPackage",
  213. new Object[]{ns, "javapackage", className + "."});
  214. }
  215. }
  216. /*
  217. public ExtensionNamespaceSupport getSupport(int index, Vector extensions)
  218. {
  219. return (ExtensionNamespaceSupport)extensions.elementAt(index);
  220. }
  221. */
  222. /**
  223. * Set up a Vector for predefined extension namespaces.
  224. */
  225. private void setPredefinedNamespaces()
  226. {
  227. String uri = Constants.S_EXTENSIONS_JAVA_URL;
  228. String handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaPackage";
  229. String lang = "javapackage";
  230. String lib = "";
  231. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  232. new Object[]{uri, lang, lib}));
  233. uri = Constants.S_EXTENSIONS_OLD_JAVA_URL;
  234. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  235. new Object[]{uri, lang, lib}));
  236. uri = Constants.S_EXTENSIONS_LOTUSXSL_JAVA_URL;
  237. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  238. new Object[]{uri, lang, lib}));
  239. uri = Constants.S_EXTENSIONS_XALANLIB_URL;
  240. handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaClass";
  241. lang = "javaclass"; // for remaining predefined extension namespaces.
  242. lib = "org.apache.xalan.lib.Extensions";
  243. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  244. new Object[]{uri, lang, lib}));
  245. // Xalan extension namespaces (redirect, pipe and SQL).
  246. uri = Constants.S_EXTENSIONS_REDIRECT_URL;
  247. lib = "org.apache.xalan.lib.Redirect";
  248. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  249. new Object[]{uri, lang, lib}));
  250. uri = Constants.S_EXTENSIONS_PIPE_URL;
  251. lib = "org.apache.xalan.lib.PipeDocument";
  252. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  253. new Object[]{uri, lang, lib}));
  254. uri = Constants.S_EXTENSIONS_SQL_URL;
  255. lib = "org.apache.xalan.lib.sql.XConnection";
  256. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  257. new Object[]{uri, lang, lib}));
  258. //EXSLT namespaces (not including EXSLT function namespaces which are
  259. // registered by the associated ElemFunction.
  260. uri = Constants.S_EXSLT_COMMON_URL;
  261. lib = "org.apache.xalan.lib.ExsltCommon";
  262. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  263. new Object[]{uri, lang, lib}));
  264. uri = Constants.S_EXSLT_MATH_URL;
  265. lib = "org.apache.xalan.lib.ExsltMath";
  266. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  267. new Object[]{uri, lang, lib}));
  268. uri = Constants.S_EXSLT_SETS_URL;
  269. lib = "org.apache.xalan.lib.ExsltSets";
  270. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  271. new Object[]{uri, lang, lib}));
  272. uri = Constants.S_EXSLT_DATETIME_URL;
  273. lib = "org.apache.xalan.lib.ExsltDatetime";
  274. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  275. new Object[]{uri, lang, lib}));
  276. uri = Constants.S_EXSLT_DYNAMIC_URL;
  277. lib = "org.apache.xalan.lib.ExsltDynamic";
  278. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  279. new Object[]{uri, lang, lib}));
  280. uri = Constants.S_EXSLT_STRINGS_URL;
  281. lib = "org.apache.xalan.lib.ExsltStrings";
  282. m_predefExtensions.addElement(new ExtensionNamespaceSupport(uri, handlerClassName,
  283. new Object[]{uri, lang, lib}));
  284. }
  285. }