1. /*
  2. * @(#)$Id: SmartTransformerFactoryImpl.java,v 1.9 2003/08/14 16:27:43 ilene Exp $
  3. *
  4. * The Apache Software License, Version 1.1
  5. *
  6. *
  7. * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
  8. * reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * 3. The end-user documentation included with the redistribution,
  23. * if any, must include the following acknowledgment:
  24. * "This product includes software developed by the
  25. * Apache Software Foundation (http://www.apache.org/)."
  26. * Alternately, this acknowledgment may appear in the software itself,
  27. * if and wherever such third-party acknowledgments normally appear.
  28. *
  29. * 4. The names "Xalan" and "Apache Software Foundation" must
  30. * not be used to endorse or promote products derived from this
  31. * software without prior written permission. For written
  32. * permission, please contact apache@apache.org.
  33. *
  34. * 5. Products derived from this software may not be called "Apache",
  35. * nor may "Apache" appear in their name, without prior written
  36. * permission of the Apache Software Foundation.
  37. *
  38. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  39. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  40. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  42. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  44. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  45. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  46. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  47. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  48. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  49. * SUCH DAMAGE.
  50. * ====================================================================
  51. *
  52. * This software consists of voluntary contributions made by many
  53. * individuals on behalf of the Apache Software Foundation and was
  54. * originally based on software copyright (c) 2001, Sun
  55. * Microsystems., http://www.sun.com. For more
  56. * information on the Apache Software Foundation, please see
  57. * <http://www.apache.org/>.
  58. *
  59. * @author G. Todd Miller
  60. *
  61. */
  62. package com.sun.org.apache.xalan.internal.xsltc.trax;
  63. import javax.xml.transform.ErrorListener;
  64. import javax.xml.transform.Source;
  65. import javax.xml.transform.Templates;
  66. import javax.xml.transform.Transformer;
  67. import javax.xml.transform.TransformerConfigurationException;
  68. import javax.xml.transform.TransformerException;
  69. import javax.xml.transform.URIResolver;
  70. import javax.xml.transform.dom.DOMResult;
  71. import javax.xml.transform.dom.DOMSource;
  72. import javax.xml.transform.sax.SAXResult;
  73. import javax.xml.transform.sax.SAXSource;
  74. import javax.xml.transform.sax.SAXTransformerFactory;
  75. import javax.xml.transform.sax.TemplatesHandler;
  76. import javax.xml.transform.sax.TransformerHandler;
  77. import javax.xml.transform.stream.StreamResult;
  78. import javax.xml.transform.stream.StreamSource;
  79. import com.sun.org.apache.xml.internal.utils.ObjectFactory;
  80. import org.xml.sax.XMLFilter;
  81. /**
  82. * Implementation of a transformer factory that uses an XSLTC
  83. * transformer factory for the creation of Templates objects
  84. * and uses the Xalan processor transformer factory for the
  85. * creation of Transformer objects.
  86. */
  87. public class SmartTransformerFactoryImpl extends SAXTransformerFactory
  88. {
  89. private SAXTransformerFactory _xsltcFactory = null;
  90. private SAXTransformerFactory _xalanFactory = null;
  91. private SAXTransformerFactory _currFactory = null;
  92. private ErrorListener _errorlistener = null;
  93. private URIResolver _uriresolver = null;
  94. /**
  95. * implementation of the SmartTransformerFactory. This factory
  96. * uses com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactory
  97. * to return Templates objects; and uses
  98. * com.sun.org.apache.xalan.internal.processor.TransformerFactory
  99. * to return Transformer objects.
  100. */
  101. public SmartTransformerFactoryImpl() { }
  102. private void createXSLTCTransformerFactory() {
  103. _xsltcFactory = new TransformerFactoryImpl();
  104. _currFactory = _xsltcFactory;
  105. }
  106. private void createXalanTransformerFactory() {
  107. final String xalanMessage =
  108. "com.sun.org.apache.xalan.internal.xsltc.trax.SmartTransformerFactoryImpl "+
  109. "could not create an "+
  110. "com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl.";
  111. // try to create instance of Xalan factory...
  112. try {
  113. Class xalanFactClass = ObjectFactory.findProviderClass(
  114. "com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl",
  115. ObjectFactory.findClassLoader(), true);
  116. _xalanFactory = (SAXTransformerFactory)
  117. xalanFactClass.newInstance();
  118. }
  119. catch (ClassNotFoundException e) {
  120. System.err.println(xalanMessage);
  121. }
  122. catch (InstantiationException e) {
  123. System.err.println(xalanMessage);
  124. }
  125. catch (IllegalAccessException e) {
  126. System.err.println(xalanMessage);
  127. }
  128. _currFactory = _xalanFactory;
  129. }
  130. public void setErrorListener(ErrorListener listener)
  131. throws IllegalArgumentException
  132. {
  133. _errorlistener = listener;
  134. }
  135. public ErrorListener getErrorListener() {
  136. return _errorlistener;
  137. }
  138. public Object getAttribute(String name)
  139. throws IllegalArgumentException
  140. {
  141. // GTM: NB: 'debug' should change to something more unique...
  142. if ((name.equals("translet-name")) || (name.equals("debug"))) {
  143. if (_xsltcFactory == null) {
  144. createXSLTCTransformerFactory();
  145. }
  146. return _xsltcFactory.getAttribute(name);
  147. }
  148. else {
  149. if (_xalanFactory == null) {
  150. createXalanTransformerFactory();
  151. }
  152. return _xalanFactory.getAttribute(name);
  153. }
  154. }
  155. public void setAttribute(String name, Object value)
  156. throws IllegalArgumentException {
  157. // GTM: NB: 'debug' should change to something more unique...
  158. if ((name.equals("translet-name")) || (name.equals("debug"))) {
  159. if (_xsltcFactory == null) {
  160. createXSLTCTransformerFactory();
  161. }
  162. _xsltcFactory.setAttribute(name, value);
  163. }
  164. else {
  165. if (_xalanFactory == null) {
  166. createXalanTransformerFactory();
  167. }
  168. _xalanFactory.setAttribute(name, value);
  169. }
  170. }
  171. /**
  172. * javax.xml.transform.sax.TransformerFactory implementation.
  173. * Look up the value of a feature (to see if it is supported).
  174. * This method must be updated as the various methods and features of this
  175. * class are implemented.
  176. *
  177. * @param name The feature name
  178. * @return 'true' if feature is supported, 'false' if not
  179. */
  180. public boolean getFeature(String name) {
  181. // All supported features should be listed here
  182. String[] features = {
  183. DOMSource.FEATURE,
  184. DOMResult.FEATURE,
  185. SAXSource.FEATURE,
  186. SAXResult.FEATURE,
  187. StreamSource.FEATURE,
  188. StreamResult.FEATURE
  189. };
  190. // Inefficient, but it really does not matter in a function like this
  191. for (int i=0; i<features.length; i++) {
  192. if (name.equals(features[i])) return true;
  193. }
  194. // Feature not supported
  195. return false;
  196. }
  197. public URIResolver getURIResolver() {
  198. return _uriresolver;
  199. }
  200. public void setURIResolver(URIResolver resolver) {
  201. _uriresolver = resolver;
  202. }
  203. public Source getAssociatedStylesheet(Source source, String media,
  204. String title, String charset)
  205. throws TransformerConfigurationException
  206. {
  207. if (_currFactory == null) {
  208. createXSLTCTransformerFactory();
  209. }
  210. return _currFactory.getAssociatedStylesheet(source, media,
  211. title, charset);
  212. }
  213. /**
  214. * Create a Transformer object that copies the input document to the
  215. * result. Uses the com.sun.org.apache.xalan.internal.processor.TransformerFactory.
  216. * @return A Transformer object.
  217. */
  218. public Transformer newTransformer()
  219. throws TransformerConfigurationException
  220. {
  221. if (_xalanFactory == null) {
  222. createXalanTransformerFactory();
  223. }
  224. if (_errorlistener != null) {
  225. _xalanFactory.setErrorListener(_errorlistener);
  226. }
  227. if (_uriresolver != null) {
  228. _xalanFactory.setURIResolver(_uriresolver);
  229. }
  230. _currFactory = _xalanFactory;
  231. return _currFactory.newTransformer();
  232. }
  233. /**
  234. * Create a Transformer object that from the input stylesheet
  235. * Uses the com.sun.org.apache.xalan.internal.processor.TransformerFactory.
  236. * @param source the stylesheet.
  237. * @return A Transformer object.
  238. */
  239. public Transformer newTransformer(Source source) throws
  240. TransformerConfigurationException
  241. {
  242. if (_xalanFactory == null) {
  243. createXalanTransformerFactory();
  244. }
  245. if (_errorlistener != null) {
  246. _xalanFactory.setErrorListener(_errorlistener);
  247. }
  248. if (_uriresolver != null) {
  249. _xalanFactory.setURIResolver(_uriresolver);
  250. }
  251. _currFactory = _xalanFactory;
  252. return _currFactory.newTransformer(source);
  253. }
  254. /**
  255. * Create a Templates object that from the input stylesheet
  256. * Uses the com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactory.
  257. * @param source the stylesheet.
  258. * @return A Templates object.
  259. */
  260. public Templates newTemplates(Source source)
  261. throws TransformerConfigurationException
  262. {
  263. if (_xsltcFactory == null) {
  264. createXSLTCTransformerFactory();
  265. }
  266. if (_errorlistener != null) {
  267. _xsltcFactory.setErrorListener(_errorlistener);
  268. }
  269. if (_uriresolver != null) {
  270. _xsltcFactory.setURIResolver(_uriresolver);
  271. }
  272. _currFactory = _xsltcFactory;
  273. return _currFactory.newTemplates(source);
  274. }
  275. /**
  276. * Get a TemplatesHandler object that can process SAX ContentHandler
  277. * events into a Templates object. Uses the
  278. * com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactory.
  279. */
  280. public TemplatesHandler newTemplatesHandler()
  281. throws TransformerConfigurationException
  282. {
  283. if (_xsltcFactory == null) {
  284. createXSLTCTransformerFactory();
  285. }
  286. if (_errorlistener != null) {
  287. _xsltcFactory.setErrorListener(_errorlistener);
  288. }
  289. if (_uriresolver != null) {
  290. _xsltcFactory.setURIResolver(_uriresolver);
  291. }
  292. return _xsltcFactory.newTemplatesHandler();
  293. }
  294. /**
  295. * Get a TransformerHandler object that can process SAX ContentHandler
  296. * events based on a copy transformer.
  297. * Uses com.sun.org.apache.xalan.internal.processor.TransformerFactory.
  298. */
  299. public TransformerHandler newTransformerHandler()
  300. throws TransformerConfigurationException
  301. {
  302. if (_xalanFactory == null) {
  303. createXalanTransformerFactory();
  304. }
  305. if (_errorlistener != null) {
  306. _xalanFactory.setErrorListener(_errorlistener);
  307. }
  308. if (_uriresolver != null) {
  309. _xalanFactory.setURIResolver(_uriresolver);
  310. }
  311. return _xalanFactory.newTransformerHandler();
  312. }
  313. /**
  314. * Get a TransformerHandler object that can process SAX ContentHandler
  315. * events based on a transformer specified by the stylesheet Source.
  316. * Uses com.sun.org.apache.xalan.internal.processor.TransformerFactory.
  317. */
  318. public TransformerHandler newTransformerHandler(Source src)
  319. throws TransformerConfigurationException
  320. {
  321. if (_xalanFactory == null) {
  322. createXalanTransformerFactory();
  323. }
  324. if (_errorlistener != null) {
  325. _xalanFactory.setErrorListener(_errorlistener);
  326. }
  327. if (_uriresolver != null) {
  328. _xalanFactory.setURIResolver(_uriresolver);
  329. }
  330. return _xalanFactory.newTransformerHandler(src);
  331. }
  332. /**
  333. * Get a TransformerHandler object that can process SAX ContentHandler
  334. * events based on a transformer specified by the stylesheet Source.
  335. * Uses com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactory.
  336. */
  337. public TransformerHandler newTransformerHandler(Templates templates)
  338. throws TransformerConfigurationException
  339. {
  340. if (_xsltcFactory == null) {
  341. createXSLTCTransformerFactory();
  342. }
  343. if (_errorlistener != null) {
  344. _xsltcFactory.setErrorListener(_errorlistener);
  345. }
  346. if (_uriresolver != null) {
  347. _xsltcFactory.setURIResolver(_uriresolver);
  348. }
  349. return _xsltcFactory.newTransformerHandler(templates);
  350. }
  351. /**
  352. * Create an XMLFilter that uses the given source as the
  353. * transformation instructions. Uses
  354. * com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactory.
  355. */
  356. public XMLFilter newXMLFilter(Source src)
  357. throws TransformerConfigurationException {
  358. if (_xsltcFactory == null) {
  359. createXSLTCTransformerFactory();
  360. }
  361. if (_errorlistener != null) {
  362. _xsltcFactory.setErrorListener(_errorlistener);
  363. }
  364. if (_uriresolver != null) {
  365. _xsltcFactory.setURIResolver(_uriresolver);
  366. }
  367. Templates templates = _xsltcFactory.newTemplates(src);
  368. if (templates == null ) return null;
  369. return newXMLFilter(templates);
  370. }
  371. /*
  372. * Create an XMLFilter that uses the given source as the
  373. * transformation instructions. Uses
  374. * com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactory.
  375. */
  376. public XMLFilter newXMLFilter(Templates templates)
  377. throws TransformerConfigurationException {
  378. try {
  379. return new com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter(templates);
  380. }
  381. catch(TransformerConfigurationException e1) {
  382. if (_xsltcFactory == null) {
  383. createXSLTCTransformerFactory();
  384. }
  385. ErrorListener errorListener = _xsltcFactory.getErrorListener();
  386. if(errorListener != null) {
  387. try {
  388. errorListener.fatalError(e1);
  389. return null;
  390. }
  391. catch( TransformerException e2) {
  392. new TransformerConfigurationException(e2);
  393. }
  394. }
  395. throw e1;
  396. }
  397. }
  398. }