You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FopServlet.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * $Id: FopServlet.java,v 1.2 2003/03/07 09:48:05 jeremias Exp $
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.servlet;
  52. import java.io.ByteArrayOutputStream;
  53. import java.io.File;
  54. import java.io.PrintWriter;
  55. import javax.servlet.ServletException;
  56. import javax.servlet.http.HttpServlet;
  57. import javax.servlet.http.HttpServletRequest;
  58. import javax.servlet.http.HttpServletResponse;
  59. import javax.xml.transform.Result;
  60. import javax.xml.transform.Source;
  61. import javax.xml.transform.Transformer;
  62. import javax.xml.transform.TransformerException;
  63. import javax.xml.transform.TransformerFactory;
  64. import javax.xml.transform.sax.SAXResult;
  65. import javax.xml.transform.stream.StreamSource;
  66. // Avalon
  67. import org.apache.avalon.framework.logger.ConsoleLogger;
  68. import org.apache.avalon.framework.logger.Logger;
  69. //FOP
  70. import org.apache.fop.apps.Session;
  71. import org.apache.fop.apps.FOPException;
  72. /**
  73. * Example servlet to generate a PDF from a servlet.
  74. * <br/>
  75. * Servlet param is:
  76. * <ul>
  77. * <li>fo: the path to a XSL-FO file to render
  78. * </ul>
  79. * or
  80. * <ul>
  81. * <li>xml: the path to an XML file to render</li>
  82. * <li>xslt: the path to an XSLT file that can transform the above XML to XSL-FO</li>
  83. * </ul>
  84. * <br/>
  85. * Example URL: http://servername/fop/servlet/FopServlet?fo=readme.fo
  86. * <br/>
  87. * Example URL: http://servername/fop/servlet/FopServlet?xml=data.xml&xslt=format.xsl
  88. * <br/>
  89. * For this to work with Internet Explorer, you might need to append "&ext=.pdf"
  90. * to the URL.
  91. *
  92. * @author <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a>
  93. * @version $Id: FopServlet.java,v 1.2 2003/03/07 09:48:05 jeremias Exp $
  94. * (todo) Ev. add caching mechanism for Templates objects
  95. */
  96. public class FopServlet extends HttpServlet {
  97. /** Name of the parameter used for the XSL-FO file */
  98. protected static final String FO_REQUEST_PARAM = "fo";
  99. /** Name of the parameter used for the XML file */
  100. protected static final String XML_REQUEST_PARAM = "xml";
  101. /** Name of the parameter used for the XSLT file */
  102. protected static final String XSLT_REQUEST_PARAM = "xslt";
  103. /** Logger to give to FOP */
  104. protected Logger log = null;
  105. /** The TransformerFactory to use to create Transformer instances */
  106. protected TransformerFactory transFactory = null;
  107. /**
  108. * @see javax.servlet.GenericServlet#init()
  109. */
  110. public void init() throws ServletException {
  111. this.log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
  112. this.transFactory = TransformerFactory.newInstance();
  113. }
  114. /**
  115. * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
  116. */
  117. public void doGet(HttpServletRequest request,
  118. HttpServletResponse response) throws ServletException {
  119. try {
  120. //Get parameters
  121. String foParam = request.getParameter(FO_REQUEST_PARAM);
  122. String xmlParam = request.getParameter(XML_REQUEST_PARAM);
  123. String xsltParam = request.getParameter(XSLT_REQUEST_PARAM);
  124. //Analyze parameters and decide with method to use
  125. byte[] content = null;
  126. if (foParam != null) {
  127. content = renderFO(foParam);
  128. } else if ((xmlParam != null) && (xsltParam != null)) {
  129. content = renderXML(xmlParam, xsltParam);
  130. } else {
  131. PrintWriter out = response.getWriter();
  132. out.println("<html><head><title>Error</title></head>\n"
  133. + "<body><h1>FopServlet Error</h1><h3>No 'fo' "
  134. + "request param given.</body></html>");
  135. }
  136. if (content != null) {
  137. //Send the result back to the client
  138. response.setContentType("application/pdf");
  139. response.setContentLength(content.length);
  140. response.getOutputStream().write(content);
  141. response.getOutputStream().flush();
  142. }
  143. } catch (Exception ex) {
  144. throw new ServletException(ex);
  145. }
  146. }
  147. /**
  148. * Converts a String parameter to a JAXP Source object.
  149. * @param param a String parameter
  150. * @return Source the generated Source object
  151. */
  152. protected Source convertString2Source(String param) {
  153. return new StreamSource(new File(param));
  154. }
  155. /**
  156. * Renders an XSL-FO file into a PDF file. The PDF is written to a byte
  157. * array that is returned as the method's result.
  158. * @param fo the XSL-FO file
  159. * @return byte[] the rendered PDF file
  160. * @throws FOPException If an error occurs during the rendering of the
  161. * XSL-FO
  162. * @throws TransformerException If an error occurs while parsing the input
  163. * file
  164. */
  165. protected byte[] renderFO(String fo)
  166. throws FOPException, TransformerException {
  167. //Setup source
  168. Source foSrc = convertString2Source(fo);
  169. //Setup the identity transformation
  170. Transformer transformer = this.transFactory.newTransformer();
  171. //Start transformation and rendering process
  172. return render(foSrc, transformer);
  173. }
  174. /**
  175. * Renders an XML file into a PDF file by applying a stylesheet
  176. * that converts the XML to XSL-FO. The PDF is written to a byte array
  177. * that is returned as the method's result.
  178. * @param xml the XML file
  179. * @param xslt the XSLT file
  180. * @return byte[] the rendered PDF file
  181. * @throws FOPException If an error occurs during the rendering of the
  182. * XSL-FO
  183. * @throws TransformerException If an error occurs during XSL
  184. * transformation
  185. */
  186. protected byte[] renderXML(String xml, String xslt)
  187. throws FOPException, TransformerException {
  188. //Setup sources
  189. Source xmlSrc = convertString2Source(xml);
  190. Source xsltSrc = convertString2Source(xslt);
  191. //Setup the XSL transformation
  192. Transformer transformer = this.transFactory.newTransformer(xsltSrc);
  193. //Start transformation and rendering process
  194. return render(xmlSrc, transformer);
  195. }
  196. /**
  197. * Renders an input file (XML or XSL-FO) into a PDF file. It uses the JAXP
  198. * transformer given to optionally transform the input document to XSL-FO.
  199. * The transformer may be an identity transformer in which case the input
  200. * must already be XSL-FO. The PDF is written to a byte array that is
  201. * returned as the method's result.
  202. * @param src Input XML or XSL-FO
  203. * @param transformer Transformer to use for optional transformation
  204. * @return byte[] the rendered PDF file
  205. * @throws FOPException If an error occurs during the rendering of the
  206. * XSL-FO
  207. * @throws TransformerException If an error occurs during XSL
  208. * transformation
  209. */
  210. protected byte[] render(Source src, Transformer transformer)
  211. throws FOPException, TransformerException {
  212. //Setup FOP
  213. Session session = new Session();
  214. session.enableLogging(this.log);
  215. session.setRenderer(Session.RENDER_PDF);
  216. session.initialize();
  217. //Setup output
  218. ByteArrayOutputStream out = new ByteArrayOutputStream();
  219. session.setOutputStream(out);
  220. //Make sure the XSL transformation's result is piped through to FOP
  221. Result res = new SAXResult(session.getContentHandler());
  222. //Start the transformation and rendering process
  223. transformer.transform(src, res);
  224. //Return the result
  225. return out.toByteArray();
  226. }
  227. }