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 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * Copyright 1999-2006 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.servlet;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import java.io.PrintWriter;
  21. import javax.servlet.ServletException;
  22. import javax.servlet.http.HttpServlet;
  23. import javax.servlet.http.HttpServletRequest;
  24. import javax.servlet.http.HttpServletResponse;
  25. import javax.xml.transform.Result;
  26. import javax.xml.transform.Source;
  27. import javax.xml.transform.Transformer;
  28. import javax.xml.transform.TransformerException;
  29. import javax.xml.transform.TransformerFactory;
  30. import javax.xml.transform.URIResolver;
  31. import javax.xml.transform.sax.SAXResult;
  32. import javax.xml.transform.stream.StreamSource;
  33. import org.apache.commons.io.output.ByteArrayOutputStream;
  34. import org.apache.commons.logging.impl.SimpleLog;
  35. import org.apache.fop.apps.FOUserAgent;
  36. import org.apache.fop.apps.Fop;
  37. import org.apache.fop.apps.FOPException;
  38. import org.apache.fop.apps.FopFactory;
  39. import org.apache.fop.apps.MimeConstants;
  40. /**
  41. * Example servlet to generate a PDF from a servlet.
  42. * <br/>
  43. * Servlet param is:
  44. * <ul>
  45. * <li>fo: the path to a XSL-FO file to render
  46. * </ul>
  47. * or
  48. * <ul>
  49. * <li>xml: the path to an XML file to render</li>
  50. * <li>xslt: the path to an XSLT file that can transform the above XML to XSL-FO</li>
  51. * </ul>
  52. * <br/>
  53. * Example URL: http://servername/fop/servlet/FopServlet?fo=readme.fo
  54. * <br/>
  55. * Example URL: http://servername/fop/servlet/FopServlet?xml=data.xml&xslt=format.xsl
  56. * <br/>
  57. * For this to work with Internet Explorer, you might need to append "&ext=.pdf"
  58. * to the URL.
  59. *
  60. * @author <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a>
  61. * @version $Id$
  62. * (todo) Ev. add caching mechanism for Templates objects
  63. */
  64. public class FopServlet extends HttpServlet {
  65. /** Name of the parameter used for the XSL-FO file */
  66. protected static final String FO_REQUEST_PARAM = "fo";
  67. /** Name of the parameter used for the XML file */
  68. protected static final String XML_REQUEST_PARAM = "xml";
  69. /** Name of the parameter used for the XSLT file */
  70. protected static final String XSLT_REQUEST_PARAM = "xslt";
  71. /** Logger to give to FOP */
  72. protected SimpleLog log = null;
  73. /** The TransformerFactory used to create Transformer instances */
  74. protected TransformerFactory transFactory = null;
  75. /** The FopFactory used to create Fop instances */
  76. protected FopFactory fopFactory = null;
  77. /** URIResolver for use by this servlet */
  78. protected URIResolver uriResolver;
  79. /**
  80. * @see javax.servlet.GenericServlet#init()
  81. */
  82. public void init() throws ServletException {
  83. this.log = new SimpleLog("FOP/Servlet");
  84. log.setLevel(SimpleLog.LOG_LEVEL_WARN);
  85. this.uriResolver = new ServletContextURIResolver(getServletContext());
  86. this.transFactory = TransformerFactory.newInstance();
  87. this.transFactory.setURIResolver(this.uriResolver);
  88. //Configure FopFactory as desired
  89. this.fopFactory = FopFactory.newInstance();
  90. this.fopFactory.setURIResolver(this.uriResolver);
  91. configureFopFactory();
  92. }
  93. /**
  94. * This method is called right after the FopFactory is instantiated and can be overridden
  95. * by subclasses to perform additional configuration.
  96. */
  97. protected void configureFopFactory() {
  98. //Subclass and override this method to perform additional configuration
  99. }
  100. /**
  101. * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
  102. */
  103. public void doGet(HttpServletRequest request,
  104. HttpServletResponse response) throws ServletException {
  105. try {
  106. //Get parameters
  107. String foParam = request.getParameter(FO_REQUEST_PARAM);
  108. String xmlParam = request.getParameter(XML_REQUEST_PARAM);
  109. String xsltParam = request.getParameter(XSLT_REQUEST_PARAM);
  110. //Analyze parameters and decide with method to use
  111. if (foParam != null) {
  112. renderFO(foParam, response);
  113. } else if ((xmlParam != null) && (xsltParam != null)) {
  114. renderXML(xmlParam, xsltParam, response);
  115. } else {
  116. response.setContentType("text/html");
  117. PrintWriter out = response.getWriter();
  118. out.println("<html><head><title>Error</title></head>\n"
  119. + "<body><h1>FopServlet Error</h1><h3>No 'fo' "
  120. + "request param given.</body></html>");
  121. }
  122. } catch (Exception ex) {
  123. throw new ServletException(ex);
  124. }
  125. }
  126. /**
  127. * Converts a String parameter to a JAXP Source object.
  128. * @param param a String parameter
  129. * @return Source the generated Source object
  130. */
  131. protected Source convertString2Source(String param) {
  132. return new StreamSource(new File(param));
  133. }
  134. private void sendPDF(byte[] content, HttpServletResponse response) throws IOException {
  135. //Send the result back to the client
  136. response.setContentType("application/pdf");
  137. response.setContentLength(content.length);
  138. response.getOutputStream().write(content);
  139. response.getOutputStream().flush();
  140. }
  141. /**
  142. * Renders an XSL-FO file into a PDF file. The PDF is written to a byte
  143. * array that is returned as the method's result.
  144. * @param fo the XSL-FO file
  145. * @param response HTTP response object
  146. * @throws FOPException If an error occurs during the rendering of the
  147. * XSL-FO
  148. * @throws TransformerException If an error occurs while parsing the input
  149. * file
  150. * @throws IOException In case of an I/O problem
  151. */
  152. protected void renderFO(String fo, HttpServletResponse response)
  153. throws FOPException, TransformerException, IOException {
  154. //Setup source
  155. Source foSrc = convertString2Source(fo);
  156. //Setup the identity transformation
  157. Transformer transformer = this.transFactory.newTransformer();
  158. transformer.setURIResolver(this.uriResolver);
  159. //Start transformation and rendering process
  160. render(foSrc, transformer, response);
  161. }
  162. /**
  163. * Renders an XML file into a PDF file by applying a stylesheet
  164. * that converts the XML to XSL-FO. The PDF is written to a byte array
  165. * that is returned as the method's result.
  166. * @param xml the XML file
  167. * @param xslt the XSLT file
  168. * @param response HTTP response object
  169. * @throws FOPException If an error occurs during the rendering of the
  170. * XSL-FO
  171. * @throws TransformerException If an error occurs during XSL
  172. * transformation
  173. * @throws IOException In case of an I/O problem
  174. */
  175. protected void renderXML(String xml, String xslt, HttpServletResponse response)
  176. throws FOPException, TransformerException, IOException {
  177. //Setup sources
  178. Source xmlSrc = convertString2Source(xml);
  179. Source xsltSrc = convertString2Source(xslt);
  180. //Setup the XSL transformation
  181. Transformer transformer = this.transFactory.newTransformer(xsltSrc);
  182. transformer.setURIResolver(this.uriResolver);
  183. //Start transformation and rendering process
  184. render(xmlSrc, transformer, response);
  185. }
  186. /**
  187. * Renders an input file (XML or XSL-FO) into a PDF file. It uses the JAXP
  188. * transformer given to optionally transform the input document to XSL-FO.
  189. * The transformer may be an identity transformer in which case the input
  190. * must already be XSL-FO. The PDF is written to a byte array that is
  191. * returned as the method's result.
  192. * @param src Input XML or XSL-FO
  193. * @param transformer Transformer to use for optional transformation
  194. * @param response HTTP response object
  195. * @throws FOPException If an error occurs during the rendering of the
  196. * XSL-FO
  197. * @throws TransformerException If an error occurs during XSL
  198. * transformation
  199. * @throws IOException In case of an I/O problem
  200. */
  201. protected void render(Source src, Transformer transformer, HttpServletResponse response)
  202. throws FOPException, TransformerException, IOException {
  203. FOUserAgent foUserAgent = getFOUserAgent();
  204. //Setup output
  205. ByteArrayOutputStream out = new ByteArrayOutputStream();
  206. //Setup FOP
  207. Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
  208. //Make sure the XSL transformation's result is piped through to FOP
  209. Result res = new SAXResult(fop.getDefaultHandler());
  210. //Start the transformation and rendering process
  211. transformer.transform(src, res);
  212. //Return the result
  213. sendPDF(out.toByteArray(), response);
  214. }
  215. /** @return a new FOUserAgent for FOP */
  216. protected FOUserAgent getFOUserAgent() {
  217. FOUserAgent userAgent = fopFactory.newFOUserAgent();
  218. //Configure foUserAgent as desired
  219. return userAgent;
  220. }
  221. }