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.

BookMaker.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. // Derived from examples/embedding/java/embedding/ExampleXML2PDF.java
  19. // in FOP-0.20.5
  20. //Java
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.io.OutputStream;
  24. import java.io.FileInputStream;
  25. import java.io.FileOutputStream;
  26. import java.util.Vector;
  27. //JAXP
  28. import javax.xml.transform.Transformer;
  29. import javax.xml.transform.TransformerFactory;
  30. import javax.xml.transform.TransformerException;
  31. import javax.xml.transform.Source;
  32. import javax.xml.transform.Result;
  33. import javax.xml.transform.stream.StreamSource;
  34. import javax.xml.transform.stream.StreamResult;
  35. import javax.xml.transform.sax.SAXSource;
  36. import javax.xml.transform.sax.SAXResult;
  37. import javax.xml.parsers.SAXParserFactory;
  38. import javax.xml.parsers.FactoryConfigurationError;
  39. import javax.xml.parsers.SAXParser;
  40. import javax.xml.parsers.ParserConfigurationException;
  41. // SAX
  42. import org.xml.sax.InputSource;
  43. import org.xml.sax.XMLReader;
  44. import org.xml.sax.SAXException;
  45. import org.xml.sax.SAXParseException;
  46. import org.xml.sax.ErrorHandler;
  47. // XML Commons
  48. import org.apache.xml.resolver.tools.CatalogResolver;
  49. import org.apache.commons.cli.Options;
  50. import org.apache.commons.cli.Option;
  51. import org.apache.commons.cli.OptionGroup;
  52. import org.apache.commons.cli.CommandLine;
  53. import org.apache.commons.cli.HelpFormatter;
  54. import org.apache.commons.cli.Parser;
  55. import org.apache.commons.cli.GnuParser;
  56. import org.apache.commons.cli.ParseException;
  57. //Avalon
  58. import org.apache.avalon.framework.ExceptionUtil;
  59. import org.apache.avalon.framework.logger.ConsoleLogger;
  60. import org.apache.avalon.framework.logger.Logger;
  61. //FOP
  62. import org.apache.fop.apps.Driver;
  63. import org.apache.fop.apps.FOPException;
  64. import org.apache.fop.messaging.MessageHandler;
  65. /**
  66. * This class converts an XML file to PDF using
  67. * JAXP (XSLT) and FOP (XSL:FO).
  68. */
  69. public class BookMaker implements ErrorHandler {
  70. private Logger logger;
  71. private File xmlFile, xsltFile, outFile, pdfFile;
  72. private boolean useCatalog;
  73. private Vector xsltParams = null;
  74. public BookMaker() {
  75. //Setup logger
  76. logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
  77. }
  78. /**
  79. * org.xml.sax.ErrorHandler#warning
  80. **/
  81. public void warning(SAXParseException e) {
  82. logger.warn(e.toString());
  83. }
  84. /**
  85. * org.xml.sax.ErrorHandler#error
  86. **/
  87. public void error(SAXParseException e) {
  88. logger.error(e.toString());
  89. }
  90. /**
  91. * org.xml.sax.ErrorHandler#fatalError
  92. **/
  93. public void fatalError(SAXParseException e) throws SAXException {
  94. logger.error(e.toString());
  95. throw e;
  96. }
  97. public void makeBook()
  98. throws IOException, FOPException, TransformerException,
  99. FactoryConfigurationError,
  100. ParserConfigurationException, SAXException {
  101. OutputStream out = null;
  102. try {
  103. Source xmlSource, xsltSource;
  104. Result result;
  105. CatalogResolver resolver = null;
  106. // Setup entity and URI resolver
  107. if (useCatalog) {
  108. resolver = new CatalogResolver();
  109. logger.info("Using " + resolver.getClass().getName()
  110. + " as entity/URI resolver");
  111. }
  112. //Setup XSLT transformer
  113. TransformerFactory tFactory = TransformerFactory.newInstance();
  114. if (useCatalog) {
  115. tFactory.setURIResolver(resolver);
  116. }
  117. //Setup input and xslt sources
  118. if (useCatalog) {
  119. SAXParser parser;
  120. XMLReader xmlReader;
  121. FileInputStream fis;
  122. InputSource is;
  123. // throws FactoryConfigurationError
  124. SAXParserFactory sFactory = SAXParserFactory.newInstance();
  125. sFactory.setNamespaceAware(true);
  126. // Setup input source
  127. // throws ParserConfigurationException
  128. parser = sFactory.newSAXParser();
  129. // throws SAXException
  130. xmlReader = parser.getXMLReader();
  131. logger.info("Using " + xmlReader.getClass().getName()
  132. + " as SAX parser");
  133. xmlReader.setErrorHandler(this);
  134. xmlReader.setEntityResolver(resolver);
  135. // Setup SAX source
  136. fis = new FileInputStream(xmlFile);
  137. is = new InputSource(fis);
  138. xmlSource = new SAXSource(xmlReader, is);
  139. // Setup xslt source
  140. // throws ParserConfigurationException
  141. parser = sFactory.newSAXParser();
  142. // throws SAXException
  143. xmlReader = parser.getXMLReader();
  144. logger.info("Using " + xmlReader.getClass().getName()
  145. + " as SAX parser");
  146. xmlReader.setErrorHandler(this);
  147. xmlReader.setEntityResolver(resolver);
  148. // Setup SAX source
  149. fis = new FileInputStream(xsltFile);
  150. is = new InputSource(fis);
  151. xsltSource = new SAXSource(xmlReader, is);
  152. } else {
  153. xmlSource = new StreamSource(xmlFile);
  154. xsltSource = new StreamSource(xsltFile);
  155. }
  156. // Setup output result
  157. if (pdfFile != null) {
  158. //Setup FOP
  159. MessageHandler.setScreenLogger(logger);
  160. Driver driver = new Driver();
  161. driver.setLogger(logger);
  162. driver.setRenderer(Driver.RENDER_PDF);
  163. out = new FileOutputStream(pdfFile);
  164. driver.setOutputStream(out);
  165. //Resulting SAX events (the generated FO)
  166. // must be piped through to FOP
  167. result = new SAXResult(driver.getContentHandler());
  168. } else {
  169. out = new FileOutputStream(outFile);
  170. result = new StreamResult(out);
  171. }
  172. // Setup the transformer
  173. Transformer transformer
  174. = tFactory.newTransformer(xsltSource);
  175. logger.info("Using " + transformer.getClass().getName()
  176. + " as TrAX transformer");
  177. // Set the value of parameters, if any, defined for stylesheet
  178. if (xsltParams != null) {
  179. for (int i = 0; i < xsltParams.size(); i += 2) {
  180. transformer.setParameter
  181. ((String) xsltParams.elementAt(i),
  182. (String) xsltParams.elementAt(i + 1));
  183. }
  184. }
  185. //Start XSLT transformation and FOP processing
  186. transformer.transform(xmlSource, result);
  187. } finally {
  188. if (out != null) {
  189. out.close();
  190. }
  191. }
  192. }
  193. private static Options createOptions() {
  194. Options options = new Options();
  195. OptionGroup og;
  196. Option o;
  197. o = new Option("h", "help", false, "Print help");
  198. options.addOption(o);
  199. o = new Option("c", "useCatalog", false, "Use catalog");
  200. options.addOption(o);
  201. o = new Option("xml", "xmlFile", true, "XML input file");
  202. o.setArgName("file");
  203. options.addOption(o);
  204. o = new Option("xsl", "xslFile", true, "XSLT stylesheet");
  205. o.setArgName("file");
  206. options.addOption(o);
  207. // mutually exclusive output options
  208. og = new OptionGroup();
  209. o = new Option("out", "outFile", true, "(X)HTML/FO output file");
  210. o.setArgName("file");
  211. og.addOption(o);
  212. o = new Option("pdf", "pdfFile", true, "PDF output file");
  213. o.setArgName("file");
  214. og.addOption(o);
  215. options.addOptionGroup(og);
  216. o = new Option("p", "parameter", true,
  217. "Parameter for the XSLT transformation");
  218. o.setArgs(2);
  219. o.setArgName("name value");
  220. options.addOption(o);
  221. return options;
  222. }
  223. public static void main(String[] args) {
  224. BookMaker app = new BookMaker();
  225. try {
  226. // Setup options
  227. Options options = createOptions();
  228. // Parse command line
  229. // GNU parser allow multi-letter short options
  230. Parser parser = new GnuParser();
  231. CommandLine cl = null;
  232. cl = parser.parse(options, args);
  233. if (cl.hasOption("h")) {
  234. // automatically generate the help statement
  235. HelpFormatter formatter = new HelpFormatter();
  236. formatter.printHelp("BookMaker", options);
  237. System.exit(0);
  238. }
  239. //Setup input and output files and parameters
  240. if (cl.hasOption("c")) {
  241. app.useCatalog = true;
  242. }
  243. if (cl.hasOption("xml")) {
  244. app.xmlFile = new File(cl.getOptionValue("xml"));
  245. }
  246. if (cl.hasOption("xsl")) {
  247. app.xsltFile = new File(cl.getOptionValue("xsl"));
  248. }
  249. if (cl.hasOption("out")) {
  250. app.outFile = new File(cl.getOptionValue("out"));
  251. }
  252. if (cl.hasOption("pdf")) {
  253. app.pdfFile = new File(cl.getOptionValue("pdf"));
  254. }
  255. if (cl.hasOption("p")) {
  256. String[] params = cl.getOptionValues("p");
  257. app.xsltParams = new Vector();
  258. for (int i = 0; i < params.length; ++i) {
  259. app.xsltParams.addElement(params[i]);
  260. }
  261. }
  262. app.logger.info("Input: XML (" + app.xmlFile + ")");
  263. app.logger.info("Stylesheet: " + app.xsltFile);
  264. if (app.pdfFile != null) {
  265. app.logger.info("Output: PDF (" + app.pdfFile + ")");
  266. } else {
  267. app.logger.info("Output: (X)HTML/FO (" + app.outFile + ")");
  268. }
  269. app.logger.info("");
  270. app.logger.info("Transforming...");
  271. app.makeBook();
  272. app.logger.info("Transforming done");
  273. } catch (Exception e) {
  274. app.logger.error(ExceptionUtil.printStackTrace(e));
  275. System.exit(1);
  276. }
  277. }
  278. }